[PYTHON] [Memo] Test code summary

What is the purpose of the test code in a nutshell?

Eliminating bugs

What is a test code?

--Work to check if it works properly --Use test code to design while moving and fixing defects --So to speak, something like a lifeline, a safety net, a bulletproof vest

What happens as a result of the test code?

--Reduced bugs and faster implementation speed --You can see the design by looking at the test code --Therefore, additional specifications become easier

There are three libraries that help you test Python.

  1. unittest

  2. doctest

  3. pytest

  4. unittest First, prepare the function calc.py to be tested. This is a method for adding and subtracting.

calc.py


def add_num(num1, num2):
    return num1 + num2

def sub_num(num1, num2):
    return num1 - num2

Then test calc.py with ʻunit test`.

** 6 steps to write a test program **

  1. The file name is "test_target module name.py".
  2. Import the unittest module.
  3. The test class name shall be "Test test target class name".
  4. The test class inherits unittest.TestCase.
  5. The test method name is "test_method name to be tested".
  6. Run the test with ʻunittest.main ()`.

test_calc.py


# 1.The file name is "test"_Target module name.py "
# 2.Import unittest module
import unittest
import calc

# 3.The test class name is "Test test target class name"
# 4.The test class is unittest.Inherit TestCase
class TestCalc(unittest.TestCase):

    # 5.The test method name is "test"_The method name to be tested "
    def test_add_num(self):
        num1 = 10
        num2 = 5
        expected = 15
        actual = calc.add_num(num1, num2)

        #Assert Equal to see if you're getting the results you want()Method
        self.assertEqual(expected, actual)

    def test_sub_num(self):
        num1 = 10
        num2 = 5
        expected = 5
        actual = calc.sub_num(num1, num2)
        self.assertEqual(expected, actual)

# 6. unittest.main()Run the test on
if __name__ == "__main__":
    unittest.main()

You can see information about the test by running it with the -v option after the file name. If the calculation is executed correctly, it is successful.


$ python test_calc.py -v

test_add_num (__main__.TestCalc) ... ok
test_div_num (__main__.TestCalc) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

Both of the target scripts are displayed as ʻok, so you can see that the test was successful. When ʻunittest.main () is executed, all the classes that inherit ʻunittest.TestCase will be recognized in the target script, and each method starting with test` will be executed as a test case.

Finally, let's look at the case where the test fails.

test_calc_1.py


# 1.The file name is "test"_Target module name.py "
# 2.Import unittest module
import unittest
import calc

# 3.The test class name is "Test test target class name"
# 4.The test class is unittest.Inherit TestCase
class TestCalc(unittest.TestCase):

    # 5.The test method name is "test"_The method name to be tested "
    def test_add_num(self):
        num1 = 10
        num2 = 5
        expected = 15
        actual = calc.add_num(num1, num2)

        #Assert Equal to see if you're getting the results you want()Method
        self.assertEqual(expected, actual)

    def test_sub_num(self):
        num1 = 10
        num2 = 5
        expected = 6
        actual = calc.sub_num(num1, num2)
        self.assertEqual(expected, actual)

# 6. unittest.main()Run the test on
if __name__ == "__main__":
    unittest.main()

$ python test_calc.py -v

test_add_num (__main__.TestCalc) ... ok
test_sub_num (__main__.TestCalc) ... FAIL

======================================================================
FAIL: test_sub_num (__main__.TestCalc)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_calc.py", line 24, in test_sub_num
    self.assertEqual(expected, actual)
AssertionError: 6 != 5

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

It says test_sub_num (__main__. TestCalc) ... FAIL, and it turns out that the result of the subtraction is incorrect.

References

-[For beginners] Think about the test code policy (what should be tested? What kind of test should be written?) -Notes on how to use Python standard unittest -[Test serialization in Python (2) How to write a unit test](https://adtech-blog.united.jp/2015/09/%e3%83%a6%e3%83%8b%e3%83%83% e3% 83% 88% e3% 83% 86% e3% 82% b9% e3% 83% 88 / python% e3% 81% a7% e3% 83% 86% e3% 82% b9% e3% 83% 88- % e9% 80% a3% e8% bc% 892-% e3% 83% a6% e3% 83% 8b% e3% 83% 83% e3% 83% 88% e3% 83% 86% e3% 82% b9% e3% 83% 88% e3% 81% ae% e6% 9b% b8% e3% 81% 8d% e6% 96% b9 /)

  1. doctest ** 3 steps to write a test program **
  2. In the function to be tested ʻadd_num and sum_num` (the part surrounded by'''), describe the function call and the expected output value in the form of Python interactive mode.
  3. Import the doctest module.
  4. Run the test with doctest.testmod ().

First, let's look at the case where there is an error.

doc.py


class Keisan(object):
    def add_num(self, num1, num2):
        # 1.Describe the function call and expected output value
        '''Add arguments
        >>> k = Keisan()
        >>> k.add_num(5, 5)
        10
        '''

        result = num1 + num2
        return result

    def sub_num(self, num1, num2):
        '''Subtract arguments
        >>> k = Keisan()
        >>> k.sub_num(5, 5)
        3
        '''

        result = num1 - num2
        return result

# 2.Import the doctest module
# 3. doctest.testmod()Run the test on
if __name__ == '__main__':
    import doctest
    doctest.testmod()
$ python doc.py

**********************************************************************
File "practice.py", line 15, in __main__.Keisan.sub_num
Failed example:
    k.sub_num(5, 5)
Expected:
    3
Got:
    0
**********************************************************************
1 items had failures:
   1 of   2 in __main__.Keisan.sub_num
***Test Failed*** 1 failures.

The expected output value is shown in Expected and the actual output value is shown in Got. You can see that Got: 0 is correct instead of ʻExpected: 3`.

Next, let's look at the case where there are no errors.

doc_1.py


class Keisan(object):
    def add_num(self, num1, num2):
        # 1.Describe the function call and expected output value
        '''Add arguments
        >>> k = Keisan()
        >>> k.add_num(5, 5)
        10
        '''

        result = num1 + num2
        return result

    def sub_num(self, num1, num2):
        '''Subtract arguments
        >>> k = Keisan()
        >>> k.sub_num(5, 5)
        0
        '''

        result = num1 - num2
        return result

# 2.Import the doctest module
# 3. doctest.testmod()Run the test on
if __name__ == '__main__':
    import doctest
    doctest.testmod()
$ python doc.py

Replaced ʻExpected: 3 with ʻExpected: 0. I found that if there were no errors, nothing was displayed.

References

-Try doctest in Python

  1. pytest

First, install pytest.

$ pip install pytest

Next, prepare the function practice.py to be tested. This is a method for adding and subtracting.

practice.py


class Practice(object):

    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

    def add_num(self):
        return self.num1 + self.num2

    def sub_num(self):
        return self.num1 - self.num2

Then test against practice.py using pytest.

** 6 steps to write a test program **

  1. The file name is "test_target module name.py".
  2. The test method name is "test_tested method name".
  3. Run the test with ʻassert`.

test_practice.py


# 1.The file name is "test"_Target module name.py "
from practice import Practice

# 2.The test method name is "test"_The method name to be tested "
def test_add_num():
    # 3.Run the test with assert
    assert Practice(5, 5).add_num() == 10

def test_sub_num():
    assert Practice(5, 5).sub_num() == 10

Execute with pytest in front of the file name.

$ pytest test_practice.py

=============================== test session starts ================================
platform win32 -- Python 3.8.2, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Yusuke\Desktop\blog\test
collected 2 items                                                                   

test_practice.py .F                                                           [100%]

===================================== FAILURES =====================================
___________________________________ test_sub_num ___________________________________

    def test_sub_num():
>       assert Practice(5, 5).sub_num() == 10
E       assert 0 == 10
E        +  where 0 = <bound method Practice.sub_num of <practice.Practice object at
0x00000210F2B21070>>()
E        +    where <bound method Practice.sub_num of <practice.Practice object at 0x
00000210F2B21070>> = <practice.Practice object at 0x00000210F2B21070>.sub_num
E        +      where <practice.Practice object at 0x00000210F2B21070> = Practice(5,
5)

test_practice.py:7: AssertionError
============================= short test summary info ==============================
FAILED test_practice.py::test_sub_num - assert 0 == 10
=========================== 1 failed, 1 passed in 0.24s ============================

The short test summary info FAILED states test_practice.py :: test_sub_num --asser 0 == 10, indicating that the result of the subtraction is incorrect.

Replace the result of the subtraction from 10 to 0 and check if there are no errors.

test_practice_1.py


# 1.The file name is "test"_Target module name.py "
from practice import Practice

# 2.The test method name is "test"_The method name to be tested "
def test_add_num():
    # 3.Run the test with assert
    assert Practice(5, 5).add_num() == 10

def test_sub_num():
    assert Practice(5, 5).sub_num() == 0
$ pytest test_practice_1.py

=============================== test session starts ================================
platform win32 -- Python 3.8.2, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Yusuke\Desktop\blog\test
collected 2 items                                                                   

test_practice.py ..                                                           [100%]

================================ 2 passed in 0.03s =================================

It is 2 passed in 0.03s, and you can see that the result was correct.

References

-How to use Python assert statements -How to use pytest and useful functions -How to use pytest for the time being

Recommended Posts

[Memo] Test code summary
Strengthen with code test ⑦
Strengthen with code test ③
Strengthen with code test ⑤
Strengthen with code test ④
Strengthen with code test ①
Summary of test method
Strengthen with code test ⑧
Strengthen with code test ⑨
Adam Paper Summary and Code
Test code for evaluating decorators
Python data type summary memo
[memo] Java FizzBuzz Code Golf
[Learning memo] Django command summary
test
Write selenium test code in python
Python parallel / parallel processing sample code summary
[Test Driven Development (TDD)] Chapter 21 Summary
Mastodon Bot Creation Memo: Part 4 Summary
Isn't it okay to write test code?
Django tutorial summary for beginners by beginners ⑤ (test)
python setup.py test the code using multiprocess