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)

We are hiring! Do you want to be our Senior Platform Engineer? Forem is hiring a Senior Platform Engineer

If you're interested in ops and site reliability and capable of dipping in to our Linux stack, we'd love your help shoring up our systems!