Directory structure for test-driven development using pytest in python

Outline

It's just a bullet point.

The most important thing is whether you can from ... import .... The directory of the self-made module and When both test module directory hierarchies are deep.

It seems that the behavior changes in 3 or more layers.

story

The sample code when the hierarchy is deep like the following structure, I couldn't find it even if I googled it, so I wrote an article.

.
├tests
│├mod
││└test_module.py
├src
│├mod
││└module.py

I saw many things like the following.

.
├tests
│└test_module.py
├src
│└module.py

does not go well

What I want to do is How do I run unittest with pytest to separate module code and test code in directories? However, this method requires you to specify module execution options.

In launch.json, you need to describe the debug configuration of all patterns for the number of modules. It seems that there is no problem if it is a small project like a tutorial, The bigger the project, the more nonsense it is.

Directory structure

The contents of the __init__.py file are all empty. What's more, you don't need __init__.py. Again, it works fine without __init__.py, and intellisense works. image.png

test

This is the actual test.

test_name.py


import pytest
from src.animal.mammal import human
from src.star import satellite

def test_human_name():
    target=human("Jane Doe")
    ans=target.name
    assert ans=="Jane Doe"

def test_satellite_name():
    target=satellite("lua")
    ans=target.name
    assert ans=="lua"

def test_human_foot_count():
    ans=human.howmanyfoot()
    assert ans==2

if __name__ == "__main__":
    pass

Module under test

star.py


class satellite():

    def __init__(self, name:str):
        self.name=name

    def name(self) -> str:
        return self.name

class planet():

    def __init__(self, name:str):
        self.name=name

    def name(self) -> str:
        return self.name

mammal.py


class human():
    def __init__(self, name:str):
        self.name=name

    @classmethod
    def name(self) -> str:
        return self.name
    
    @staticmethod
    def howmanyfoot() -> int:
        return 2

Path setting

This is an error workaround when processing from import of" Currrent file debugging ". By putting this, it seems that it will recognize "Python path" and "self-made module of other hierarchy".

.env


PYTHONPATH=./

It recognizes even if you are using a virtual environment such as conda.

If you execute the following script, You can see if the environment is recognized.

import_test.py


import sys
print(sys.path)

As a result of executing ʻimport_test.pyabove, It is OK if./src/` is included.

Debug configuration

It defines three types of debugging methods. From top to bottom

--Test_name Module debugging --Module debugging of mammal module --Debug the file where the cursor is placed with vscode

In my personal opinion, module debugging is It is limited to applications such as specifying the main module.

In most cases, press the F5 key on the tab being edited to debug the current file → test execution flow.

launch.json


{
    //You can use IntelliSense to learn the available attributes.
    //Hover and display the description of existing attributes.
    //Check the following for more information: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        
        {
            "name": "Python:Module test_name",
            "type": "python",
            "request": "launch",
            "cwd": "${workspaceFolder}",
            "module": "tests.test_mod.test_name"
        },{
            "name": "Python:Module mammal",
            "type": "python",
            "request": "launch",
            "cwd": "${workspaceFolder}",
            "module": "src.animal.mammal"
        },
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}

Workspace settings

--Folder where the test module is located --Which testing framework to use --Specify a file that describes which python environment to use --Even if you are using a virtual environment such as conda, it will be recognized by this.

settings.json


{
    "python.testing.pytestArgs": [
        "tests"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.pytestEnabled": true,
    "python.envFile": "${workspaceFolder}/.env"
}

If you look closely, you can see that the location of .env is specified by default.

image.png

test results

image.png

environment

Excelsior!

Recommended Posts

Directory structure for test-driven development using pytest in python
Notes for using python (pydev) in eclipse
C-like structure in Python
Framework development in Python
Development environment in Python
Slackbot development in Python
AWS SDK for Python (Boto3) development in Visual Studio 2017
Search for strings in Python
Techniques for sorting in Python
Python development in Visual Studio 2017
[For organizing] Python development environment
Python development in Visual Studio
Translate using googletrans in Python
Using Python mode in Processing
About "for _ in range ():" in python
Building a development environment for Android apps-creating Android apps in Python
Explosive speed! Using Python Simple HTTP Server for kintone development
Try using the services that support serverless development that appeared in 2020 (CDK Pipelines / CodeArtifact / CodeGuru for Python)
Check for memory leaks in Python
Things to watch out for when using default arguments in Python
GUI programming in Python using Appjar
Learning history for participating in team app development in Python ~ Django Tutorial 5 ~
Check for external commands in python
Precautions when using pit in Python
Learning history for participating in team application development in Python ~ Index page ~
Learning history for participating in team app development in Python ~ Django Tutorial 4 ~
Build a local development environment for Lambda + Python using Serverless Framework
Web application development memo in python
Use watchdog (watchmedo) in test-driven development
Try using LevelDB in Python (plyvel)
Learning history for participating in team app development in Python ~ Django Tutorial 1, 2, 3 ~
Python development environment options for May 2020
Using global variables in python functions
[TouchDesigner] Tips for for statements using python
Emacs settings for Python development environment
Learning history for participating in team app development in Python ~ Django Tutorial 6 ~
Let's see using input in python
Infinite product in Python (using functools)
Learning history for participating in team app development in Python ~ Django Tutorial 7 ~
Edit videos in Python using MoviePy
[Python] Reasons for overriding using super ()
Run unittests in Python (for beginners)
[Python] Multiplication table using for statement
Handwriting recognition using KNN in Python
[Pytest] [mock] Web development beginners summarized unit test and mock in python.
Try using Leap Motion in Python
Depth-first search using stack in Python
When using regular expressions in Python
Try using FireBase Cloud Firestore in Python for the time being
Command for the current directory Python
GUI creation in python using tkinter 2
Prepare Python development environment for each project in Windows environment (VSCode + virtualEnvWrapper + Pylint)
Development and deployment of REST API in Python using Falcon Web Framework
A useful note when using Python for the first time in a while
Notes for using OpenCV on Windows10 Python 3.8.3.
Notes using cChardet and python3-chardet in Python 3.3.1.
Try using the Wunderlist API in Python
GUI creation in python using tkinter part 1
Get Suica balance in Python (using libpafe)
(Bad) practice of using this in Python
Slowly hash passwords using bcrypt in Python