DEV Community

Namah Shrestha
Namah Shrestha

Posted on

Chapter 3: Using PyTest, MyPy and flake8 for testing

3.1 Adding new dependencies to requirements

  • Now we need to install more libraries. Namely pytest, mypy and flake8.
  • So our requirements.txt file looks something like this. We have added dependencies for pytest:

    flake==3.9.4 tox==3.24.3 pytest==6.2.5 pytest-cov==2.12.1 mypy==0.910 
  • Instead of directly overwriting the requirements.txt file, we create a new file called requirements_dev.txt. Since testing is required in dev environment.

  • So we have two requirement files:

    • requirements.txt which we use while running our code:

      requests==2.26.0 
    • requirements_dev.txt which holds dev dependencies like our test, lint and type check libraries.

      flake==3.9.4 tox==3.24.3 pytest==6.2.5 pytest-cov==2.12.1 mypy==0.910 
  • While running tests we will use requirements_dev.txt file to install dependencies.

3.2 Adding to our metadata in setup.cfg

  • Our setup.cfg file looks something like this:

     [metadata] name = something description = just some dummy codebase author = Coding with Zim license = MIT license_file = LICENSE platforms = unix, linux, osx, cygwin, win32 classifiers = Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 [options] packages = something install_requires = requests>=2 python_requires = >=3.6 package_dir = =src zip_safe = no [options.extras_require] testing= pytest>=6.0 pytest-cov>=2.0 mypy>=0.910 flake8>=3.9 tox>=3.24 [options.package_data] something = py.typed [flake8] max-line-length = 160 
  • options.extras_require are optional dependencies. We can read more about it here: https://setuptools.pypa.io/en/latest/userguide/dependency_management.html

  • options.package_data is a type of Data File Support , we can read more about it here: https://setuptools.pypa.io/en/latest/userguide/datafiles.html. We are basically using it to denote that our code is type-hinted, which means we are using types in the code.

  • For this to work we need to create a py.typed blank file in our something directory alongside __init__.py.

  • flake8 is the configuration for the flake8 linter that we will be using. Here we are only saying that the maximum line length is 160.

  • So our flake8 configuration is stored in the cfg file and our python configuration is stored in our pyproject.toml file.

3.3 Adding python configurations to pyproject.toml

  • Our pyproject.toml file looks something like this:

    [build-system] requires = ["setuptools>=42.0", "wheel"] build-backend = "setuptools.build_meta" [tool.pytest.ini_options] addopts = "--cov=something" testpaths = [ "tests", ] [tool.mypy] mypy_path = "src" check_untyped_defs = true disallow_any_generics = true ignore_missing_imports = true no_implicit_optional = true show_error_codes = true strict_equality = true warn_redundant_casts = true warn_return_any = true warn_unreachable = true warn_unused_configs = true no_implicit_reexport = true 
  • We already discussed about the build-system.

  • tool.pytest.ini_options are pytest tool options during the execution of tests. In our case we have added the --cov=something option in addopts so that we see the test coverage. testpaths basically denotes all the directories containing tests.

  • tool.mypy are mypy tool options. To learn about mypy: https://realpython.com/lessons/type-checking-mypy/#:~:text=“Mypy is an optional static,background on the Mypy project.

  • So, now we install the dev dependencies with pip:

    (env)yourproject$ pip install -r requirements_dev.txt 
  • Finally we should be able to run our test with pytest, check linting with flake8 and type check with mypy.

    $ pytest # this command will test our code with default test discovery mechanism. $ mypy # this command will run type checks on our code with mypy. $ flake8 # this command will check code linting. 

Top comments (0)