1. 程式人生 > 實用技巧 >Unittest of Python

Unittest of Python

Assert -- 內建類UNIT TEST API

https://realpython.com/python-testing/

You can write both integration tests and unit tests in Python. To write a unit test for the built-in function sum(), you would check the output of sum() against a known output.

For example, here’s how you check that the sum() of the numbers (1, 2, 3)

equals 6:

>>> assert sum([1, 2, 3]) == 6, "Should be 6"

This will not output anything on the REPL because the values are correct.

If the result from sum() is incorrect, this will fail with an AssertionError and the message "Should be 6". Try an assertion statement again with the wrong values to see an AssertionError

:

>>> assert sum([1, 1, 1]) == 6, "Should be 6"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: Should be 6

In the REPL, you are seeing the raised AssertionError because the result of sum() does not match 6.

https://www.cnblogs.com/shangren/p/8038935.html

那麼我們什麼時候應該使用斷言呢?如果沒有特別的目的,斷言應該用於如下情況:

  • 防禦性的程式設計
  • 執行時對程式邏輯的檢測
  • 合約性檢查(比如前置條件,後置條件)
  • 程式中的常量
  • 檢查文件

這裡是我建議不使用斷言的情況:

*不要用於測試使用者提供的資料,或者那些需要在所有情況下需要改變檢查的地方

*不要用於檢查你認為在通常使用中可能失敗的地方。斷言用於非常特別的失敗條件。你的使用者絕不看到一個AssertionError,如果看到了,那就是個必須修復的缺陷。

*特別地不要因為斷言只是比一個明確的測試加一個觸發異常矮小而使用它。斷言不是懶惰的程式碼編寫者的捷徑。

*不要將斷言用於公共函式庫輸入引數的檢查,因為你不能控制呼叫者,並且不能保證它不破壞函式的合約。

*不要將斷言用於你期望修改的任何錯誤。換句話,你沒有任何理由在產品程式碼捕獲一個AssertionError異常。

*不要太多使用斷言,它們使程式碼變得晦澀難懂。

Test runner Comparsion

pytest 簡單易用, 且相容 unittest。是現在最流行的 python單元測試框架。

https://github.com/renzon/pytest-vs-unittest

Comparison between pytest and unittes test frameworks

##Comparison Table

FeaturePytestUnittestWinner
Installation Third Party Built in Unittest
Basic Infra Can be only a function Inheritance Pytest
Basic Assertion Builtin assert TestCase instance methods Pytest
Flat is better than nested Function (1 level) Method (2 level) Pytest
Can run each other test Can run unittest tests Can't pytest test Pytest
Test Result on console Error Highlight, code snippet Only line error, no highlight Pytest
Multi param test Yes, parametrize, keep flat Yes, sub-test, increase nesting Pytest
Test setup fixture: module, session, function Template Method: setup, tearDown Pytest
Name Refactoring poor, because of name conventions rich, regular object orientation Unittest
Running Failed Tests built in (--lf, --ff) your own =,( Pytest
Marks built in your own =,( Pytest

https://knapsackpro.com/testing_frameworks/difference_between/pytest/vs/unittest

pytest

https://docs.pytest.org/en/latest/

unittest

https://docs.Python.org/3/library/unittest.html
Programming language

Python

Python

Category

Unit Testing

Unit Testing

General info

Pytest is the TDD 'all in one' testing framework for Python

Pytest is a powerful Python testing framework that can test all and levels of software. It is considered by many to be the best testing framework in Python with many projects on the internet having switched to it from other frameworks, including Mozilla and Dropbox. This is due to its many powerful features such as ‘assert‘ rewriting, a third-party plugin model and a powerful yet simple fixture model.

unittest is a unit testing framework for Python

The unittest test framework is Python’s xUnit style framework. It is a standard module that is bundled with Python and supports the automation and aggregation of tests and common setup and shutdown code for them.
xUnit
Set of frameworks originating from SUnit (Smalltalk's testing framework). They share similar structure and functionality.

No

Yes

unittest is a xUnit style frameworkfor Python, it was previously called PyUnit.
Client-side
Allows testing code execution on the client, such as a web browser

Yes

pytest can test any part of the stack including front-end components

Yes

Front-end functionality and behaviour can be tested by unittest.
Server-side
Allows testing the bahovior of a server-side code

Yes

pytest is powerful enough to test database and server components and functionality

Yes

Since the webserver funtionalities have their own features and each feature has its own functions, we can write tests with unittest to test each function
Fixtures
Allows defining a fixed, specific states of data (fixtures) that are test-local. This ensures specific environment for a single test

Yes

Pytest has a powerful yet simple fixture model that is unmatched in any other testing framework.

Yes

By use of the 'setUp()' function which is called to prepare the test fixture
Group fixtures
Allows defining a fixed, specific states of data for a group of tests (group-fixtures). This ensures specific environment for a given group of tests.

Yes

Pytest's powerful fixture model allows grouping of fixtures

Yes

unittest allows you to group your initialization code into a setUp function and clean up code in a tearDown function
Generators
Supports data generators for tests. Data generators generate input data for test. The test is then run for each input data produced in this way.

Yes

pytest has a hook function called pytest_generate_tests hook which is called when collecting a test function and one can use it to generate data

Yes

unittest contains generator methods in the module 'unittest.TestCase'
Licence
Licence type governing the use and redistribution of the software

MIT License

MIT License

Mocks
Mocks are objects that simulate the behavior of real objects. Using mocks allows testing some part of the code in isolation (with other parts mocked when needed)

Yes

By either using unittest.mock or using pytest-mock a thin wrapper that provides mock functionality for pytest

Yes

Mocks are available from the library unittest.mock which allows you to replace parts of your system under test with mock objects
Grouping
Allows organizing tests in groups

Yes

Tests can be grouped with pytest by use of markers which are applied to various tests and one can run tests with the marker applied

Yes

One can build suites either manually or use test discovery to build the suite automatically by scanning a directory
Other
Other useful information about the testing framework

pytest

https://docs.pytest.org/en/reorganize-docs/index.html

pytest is a framework that makes building simple and scalable tests easy. Tests are expressive and readable—no boilerplate code required. Get started in minutes with a small unit test or complex functional test for your application or library.

pytest: helps you write better programs

a mature full-featured Python testing tool

Demo code

https://github.com/renzon/pytest-vs-unittest/blob/master/test/test_pytest/test_basic.py

def test_basic_stuff():
    assert True


def test_list():
    lst = [1, 3, 5, 6]
    assert [1, 3, 4] == lst


def test_string():
    assert 'unitest' == 'unittest'

目錄佈置

集中式和分散式同時支援。

https://docs.pytest.org/en/reorganize-docs/new-docs/user/directory_structure.html

pytest supports two common test layouts:

  • putting tests into an extra directory outside your actual application code, useful if you have many functional tests or for other reasons want to keep tests separate from actual application code (often a good idea):

    setup.py   # your setuptools Python package metadata
    src/
        __init__.py
        appmodule.py
        module1/
            part1.py
            part2.py
        ...
    tests/
        test_appmodule.py
        module1/
            test_part1.py
            test_part2.py
        ...
    
  • inlining test directories into your application package, useful if you have direct relation between (unit-)test and application modules and want to distribute your tests along with your application:

    setup.py   # your setuptools Python package metadata
    src/
        __init__.py
        appmodule.py
        tests/
            test_appmodule.py
        module1/
            part1.py
            part2.py
            tests/
                test_part1.py
                test_part2.py
        ...
    

Typically you can run tests by pointing to test directories or modules:

pytest tests/test_appmodule.py      # for external test dirs
pytest src/tests/test_appmodule.py  # for inlined test dirs
pytest src                          # run tests in all below test directories
pytest                              # run all tests below current dir
...

You shouldn’t have __init__.py files in your test directories.