The idioms that pytest first introduced brought a change in the Python community because they made it possible for test suites to be written in a very compact style, or at least far more compact than was ever possible before.
Pytest basically introduced the concept that Python tests should be plain Python functions instead of forcing developers to include their tests inside large test classes.
Pytest can easily be extended with several hooks, and the same team develops a number of very useful plugins. For example, you install pytest-xdist, and parallel test execution just works, with all the same benefits you had with pytest (as opposed to having to use a separate test runner, for example)
A fixture is just a function that returns a value and to use a fixture you just have to add an argument to your test function. You can also use a fixture from another fixture in the same manner, so it's easy to make them modular.
You can also parametrize fixture and every test that uses it will run with all values of parameters, no test rewrite needed. If your test uses several fixtures, all parameters' combinations will be covered.
With most other tools you have to use debugger or extra logging to find out where did some value came from in your test. Not with pytest!
Pytest rewrites your test so that it can store all intermediate values that can lead to failing assert and provides you with very pretty explanation about what has been asserted and what have failed.
Pytest automagically (and safely) disables output capturing when you're entering pdb, so you don't have to redirect debugger to other console or bear huge amount of unneeded output from other tests.
Pytest provides developers with special routines to make test writing easier. This makes writing tests less error-prone and all around simple. It also results in shorter and more readable code.
The fact that pytest uses it's own special routines to write tests means that you are trading convenience for compatibility. In other words, writing tests for pytest means that you are tying yourself to only pytest and the only way to use another testing framework is to rewrite most of the code.
According to documentation at https://nose.readthedocs.io/en/latest/, nose may become unsupported. There is a successor project called Nose2 (https://github.com/nose-devs/nose2), but it does not support all the features of its predecessor and recommends considering pytest for those new to testing.
Having lots of plugins while beneficial, also can be a hindrance. Relying too much on them makes developers feel as if everything's being done by plugins which a lot of times are undocumented or have very little documentation.
There's a large number of plugins available for nose which make unit testing easier. Things like coverage reporting, test selection and xUnit-compatible test output can be added through plugins.
PyUnit has been a part of the Python standard library since version 2.1 as the unittest module. This makes it widely available to developers without the need to install additional modules since it's coming out of the box with Python.
The way tests are run is through:
if name == 'main':
unittest.main()
Then unittest.main() builds a TestSuite object that contains all the tests that have method names starting with "test", then a TextTestRunnerwhich then executes each method and prints the results.
But individual test cases can be executed simply by specifying their names on the terminal:
python unittest_program.py testProgram.testGetFeedPostingHost
The default output is usually pretty concise, but it can be more verbose simply by adding a -v flag in the end when calling the test from the command line.
So unittest can be considered pretty flexible when it comes to test case execution.
Idiomatic python code uses snake_case, but this was ported so closely from JUnit that it has retained java-style camelCase method names. That can be jarring.
Since pyUnit is a derivative of xUnit and it's quite similar to other xUnit frameworks, it's quite easy for people with not much Python background to relate to.
Although unittest does not have a huge API that needs to be remembered, it has too much support for abstraction, this makes the test code intent's unclear.