[PYTHON] Write flexible unittests with PyHamcrest!

Introduction

Is there a List type in the Dict type in the python unit test, and it passes or does not pass every time you test? I was worried about it, so I will write it down here. The clue to the solution was given from this site (1). Thank you.

Where assertEqual cannot handle

Here I wrote the following test with reference to (2).

import unittest


class VTest(unittest.TestCase):

    maxDiff = None

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_v(self):
         first_json = {
            'kind': 'voiceroid',
            'items': [
                {'name': 'aoi'},
                {'name': 'akane'},
                {'name': 'yukari'}
            ]
        }

        second_json = {
            'kind': 'voiceroid',
            'items': [
                {'name': 'yukari'},
                {'name': 'aoi'},
                {'name': 'akane'},
            ]
        }
        self.assertEqual(first_json, second_json)


if __name__ == "__main__":
    unittest.main()

At this time, the order of the items does not matter-as long as there are contents ... So, personally, this is a test OK. But when you actually move it

F
======================================================================
FAIL: test_v (__main__.VTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".\v_test.py", line 34, in test_v
    self.assertEqual(first_json, second_json)
AssertionError: {'kin[20 chars]ems': [{'name': 'aoi'}, {'name': 'akane'}, {'name': 'yukari'}]} != {'kin[20 chars]ems': [{'name': 'yukari'}, {'name': 'aoi'}, {'name': 'akane'}]}
- {'items': [{'name': 'aoi'}, {'name': 'akane'}, {'name': 'yukari'}],
+ {'items': [{'name': 'yukari'}, {'name': 'aoi'}, {'name': 'akane'}],
   'kind': 'voiceroid'}

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

I get angry like this. No, personally ... I can't say anything that isn't good. That is the ```assertEqual function `` `. Therefore, PyHamcrest (3) is a library that flexibly responds to the request that values are important but no order is required. Because it is an external library

pip install PyHamcrest

After installing with, rewrite the above code as follows.

from hamcrest import *
import unittest


class VTest(unittest.TestCase):

    maxDiff = None

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_v(self):
        first_json = {
            'kind': 'voiceroid',
            'items': [
                {'name': 'aoi'},
                {'name': 'akane'},
                {'name': 'yukari'}
            ]
        }

        second_json = {
            'kind': 'voiceroid',
            'items': [
                {'name': 'yukari'},
                {'name': 'aoi'},
                {'name': 'akane'}
            ]
        }

        # self.assertEqual(first_json, second_json)
        assert_that(first_json, second_json)


if __name__ == "__main__":
    unittest.main()

This just changed the assertEqual function `` `to the assert_that function` ``. Then, when I test it ...

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

You passed it cleanly.

at the end

If you are in trouble because the elements are important but the order is not so important, why not give it a try? PyHamcrest Tutorial (4) is here. There are many, so please try other ones. I'm sure the test will be flexible!

reference

(1) Python unittest - asserting dictionary with lists (2) Python test code to try in the shortest time (3) PyHamcrest (4) PyHamcrest Tutorial

Recommended Posts

Write flexible unittests with PyHamcrest!
Easily write if-elif with lambda
Let's write python with cinema4d.
Write to csv with Python
[Python] Write to csv file with Python
Write a Residual Network with TFLearn
Write FW to TWE-Lite with TWE-Lite R.
Write Reversi AI with Keras + DQN
Write a stacked histogram with matplotlib
Write a batch script with Python3.5 ~