Skip to main content

Automatically convert unittests to pytest

Project description

pytestify

alt alt

A tool to automatically change unittest to pytest. Similar to unittest2pytest, but with a few more features and written using AST and tokenize, rather than lib2to3.

Big thanks to pyupgrade, which this project has learned from.

Installation

pip install pytestify

Usage

pytestify path/to/file.py

or

pytestify path/to/folder/

Optional arguments

Please read over all changes that pytestify makes. It's a new package, so there are bound to be issues.

Implemented features

Test class names

Remove TestCase parent class, and make sure tests start with Test. We are keeping the test classes themselves, but you can remove them manually.

class TestThing(unittest.TestCase):  # class TestThing:
class TestThing(TestCase, ClassB):   # class TestThing(ClassB):
class ThingTest(unittest.TestCase):  # class TestThing:
class Thing(unittest.TestCase):      # class TestThing:

Setup / teardowns

def setUp(self):          # def setup_method(self):
def tearDown(self):       # def teardown_method(self):
def setUpClass(self):     # def setup_class(self):
def tearDownClass(self):  # def teardown_class(self):

Asserts

Rewrite unittest assert methods using the assert keyword.

# asserting one thing
self.assertTrue(a)       # assert a
self.assertFalse (a)     # assert not a
self.assertIsNone(a)     # assert a is None
self.assertIsNotNone(a)  # assert a is not None

# asserting two things
self.assertEqual(a, b)      # assert a == b
self.assertNotEqual(a, b)   # assert a != b
self.assertIs(a, b)         # assert a is b
self.assertIsNot(a, b)      # assert a is not b
self.assertIn(a, b)         # assert a in b
self.assertNotIn(a, b)      # assert a not in b
self.assertListEqual(a, b)  # assert a == b
self.assertDictEqual(a, b)  # assert a == b
self.assertSetEqual(a, b)   # assert a == b
self.assertGreater(a, b)    # assert a > b
self.assertLess(a, b)       # assert a < b
self.assertGreaterEqual(a, b)  # assert a >= b
self.assertLessEqual(a, b)  # assert a <= b
self.assertRegex(a, b)      # assert a.search(b)
self.assertNotRegex(a, b)   # assert not a.search(b)

self.assertAlmostEqual(a, b)
#   assert a == pytest.approx(b)
self.assertAlmostEqual(a, b, places=2)
#   assert a == pytest.approx(b, abs=0.01)
self.assertAlmostEquals(a, b, delta=2)
#   assert a == pytest.approx(b, abs=2)


# improves the assert if reasonable
self.assertEqual(a, None)   # assert a is None
self.assertEqual(a, True)   # assert a is True


# error messages
self.assertTrue(a, msg='oh no!')  # assert a, 'oh no!'

Multi-line asserts

Since assert (a == b, 'err') is equivalent to asserting a tuple, and thus is always True.

self.assertEqual(    # assert a == \
    a,               #     b
    b,
)

self.assertEqual(    # assert a == \
    a,               #     b, \
    b,               #     'oh no!'
    msg='oh no!'
)

camelCase to snake_case

Disable this behavior with --keep-method-casing

def testThing(self):      # def test_thing(self):
def testHTTPThing(self):  # def test_httpthing(self):

assertCountEqual

The assertCountEqual rewrite is risky, so opt-in with pytest path/to/file --with-count-equal.

self.assertItemsEqual(a, b)  # assert sorted(a) == sorted(b)
self.assertCountEqual(a, b)  # assert sorted(a) == sorted(b)

Note that pytest has no version of either of these methods. See this thread for more information. You can also use unittest's implementation.

Exceptions

self.assertRaises(OSError)             # pytest.raises(OSError)
self.assertWarns(OSError)              # pytest.warns(OSError)
with self.assertRaises(OSError) as e:  # with pytest.raises(OSError) as e
with self.assertWarns(OSError) as e:   # with pytest.warns(OSError) as e

Skipping / Expecting failure

# decorated
@unittest.skip('some reason')    # @pytest.mark.skip('some reason')
@unittest.skipIf(some_bool)      # @pytest.mark.skipif(some_bool)
@unittest.skipUnless(some_bool)  # @pytest.mark.skipif(not some_bool)
@unittest.expectedFailure        # @pytest.mark.xfail

# not decorated
unittest.skip('some reason')     # pytest.skip('some reason')
unittest.skipTest('some reason') # pytest.skip('some reason')
unittest.fail('some reason')     # pytest.fail('some reason')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytestify-1.5.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

pytestify-1.5.0-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file pytestify-1.5.0.tar.gz.

File metadata

  • Download URL: pytestify-1.5.0.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.3

File hashes

Hashes for pytestify-1.5.0.tar.gz
Algorithm Hash digest
SHA256 7a144c30f3a353875e3c63724f3f5eb562946dcb7b9619b6fcd004f4973985a8
MD5 64c5ae80e08e924a9c0d29da0d0ec069
BLAKE2b-256 412e0a76b242e7c67a542c86657d01d7088faf6faaaab99b7184603b51e5c482

See more details on using hashes here.

File details

Details for the file pytestify-1.5.0-py3-none-any.whl.

File metadata

  • Download URL: pytestify-1.5.0-py3-none-any.whl
  • Upload date:
  • Size: 14.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.3

File hashes

Hashes for pytestify-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 acee4a3c40f4c7b3ce40007097d9e01088ae42dbbfbe254428e97033073aa119
MD5 3e3360809decc08b7de0bcf2c4eeeba7
BLAKE2b-256 f795a9b23475f6086febba0ffd4b1560ede1fd98d3b8f219216bea479bd16e99

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page