If you write go table driven test in python, it may be better to use subTest

Introduction

It seems that people in the go area prefer to write unit tests in a format called table driven test (although other languages do the same). I didn't invent it because it existed or existed).

I thought about what to do if I wrote a table driven test in python.

It's long to write normally with unittest

For example, suppose you want to test a function called add like this:

def add(x, y):
    return x + y

If you write it honestly within the range of the unittest module of python, it looks like the following.

import unittest


class Tests(unittest.TestCase):
    def _callFUT(self, x, y):
        from add import add
        return add(x, y)

    def test_with_positive(self):
        actual = self._callFUT(10, 10)
        self.assertEqual(actual, 20)

    def test_with_zero(self):
        actual = self._callFUT(10, 0)
        self.assertEqual(actual, 10)

    def test_with_negative(self):
        actual = self._callFUT(10, -10)
        self.assertEqual(actual, 0)

    def test_with_biiiiiiiiiig(self):
        actual = self._callFUT(
            10,
            10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
        )
        self.assertEqual(
            actual,
            10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,
        )

long. I'm tired.

(CallFUT is religious. See this area for details)

table driven test

The table driven test gives a crisp feeling. It seems good to use subTest.

import unittest
from collections import namedtuple


class Tests(unittest.TestCase):
    def _callFUT(self, x, y):
        from add import add
        return add(x, y)

    def test_it(self):
        C = namedtuple("C", "msg x y expected")
        candidates = [
            C(msg="with positive", x=10, y=10, expected=20),
            C(msg="with zero", x=10, y=0, expected=10),
            C(msg="with negative", x=10, y=-10, expected=0),
            C(
                msg="with biiiiiiig",
                x=10,
                y=10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
                expected=10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,
            ),
        ]
        for c in candidates:
            with self.subTest(msg=c.msg):
                actual = self._callFUT(c.x, c.y)
                self.assertEqual(actual, c.expected)

Below are my personal preferences

--Using namedtuple --Write msg together --_callFUT (If the test method ends with one, it may not be necessary to separate it)

How to count the number of subTest

If successful, it will be counted as one.

.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK

If it fails, it will be counted as N, which is good.


======================================================================
FAIL: test_it (__main__.Tests) [with positive]
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 26, in test_it
    self.assertEqual(actual, c.expected + 1)
AssertionError: 20 != 21

======================================================================
FAIL: test_it (__main__.Tests) [with zero]
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 26, in test_it
    self.assertEqual(actual, c.expected + 1)
AssertionError: 10 != 11

======================================================================
FAIL: test_it (__main__.Tests) [with negative]
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 26, in test_it
    self.assertEqual(actual, c.expected + 1)
AssertionError: 0 != 1

======================================================================
FAIL: test_it (__main__.Tests) [with biiiiiiig]
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 26, in test_it
    self.assertEqual(actual, c.expected + 1)
AssertionError: 10000[33 chars]000000000000000000000000000000000000000000000000000000000000010 != 10000[33 chars]000000000000000000000000000000000000000000000000000000000000011

----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (failures=4)

When using pytest

Can anyone write about a table driven test using pytest?

Recommended Posts

If you write go table driven test in python, it may be better to use subTest
If you write TinderBot in Python, she can do it
Don't write Python if you want to speed it up with Python
If you want to count words in Python, it's convenient to use Counter.
Two document generation tools that you definitely want to use if you write python
If you use Pandas' Plot function in Python, it is really seamless from data processing to graph creation
I want to write in Python! (2) Let's write a test
Understand Python yield If you put yield in a function, it will change to a generator
As you may know, Python can be written like this
If you write TinderBot in Python, she can do it
Python code that keeps tweeting "Bals" as much as you can
Write selenium test code in python
If you know Python, you can make a web application with Django
You should know if you use Python! 10 useful libraries
Write code to Unit Test a Python web app
How much do you know the basics of Python?
If you don't understand mathematical symbols, you can write a program.
If __name__ == Raise your hand, if you write the code under'__main__'
If you write go table driven test in python, it may be better to use subTest
If you want to use field names with hyphens when updating firestore data in python
It may be a problem to use Japanese for folder names and notebook names in Databricks
[Python] How to write an if statement in one sentence.
[Road to intermediate Python] Use if statement in list comprehension
To write a test in Go, first design the interface
processing to use notMNIST data in Python (and tried to classify it)
What to do if you get a minus zero in Python
[python] python's configparser may be better than managing settings in yaml
[Python] When you want to use all variables in another file
Difference in how to write if statement between ruby ​​and python
If you want to assign csv export to a variable in python
Indispensable if you use Python! How to use Numpy to speed up operations!
What to do if you can't use the trash in Lubuntu 18.04.
Implement Table Driven Test in Java
How to use SQLite in Python
Write selenium test code in python
How to use Mysql in python
How to use ChemSpider in Python
How to use PubChem in Python
If pip stops due to SSL, it is better to re-insert python itself
When writing a test using DB with django, you may be able to do it faster by using `setUpTestData ()`
Write the test in a python docstring
How to use Google Test in C
How to display multiplication table in python
Easy way to use Wikipedia in Python
How to use __slots__ in Python class
How to use is and == in Python
How to write Ruby to_s in Python
If you add sudo on ubuntu, it will be called the default python.
[Python] How to name table data and output it in csv (to_csv method)
If you write the View decorator in urls.py in Django, the list will be higher.
Use PIL in Python to extract only the data you want from Exif
If an exception occurs in the function, it will be transmitted to the caller 2
What to do if you get "Python not configured." Using PyDev in Eclipse
How to write files that you should be careful about in all languages
If you want to make a discord bot with python, let's use a framework
If an exception occurs in the function, it will be transmitted to the caller 1
If you try to install Python2 pip after installing Python3 pip and it is rejected