Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test packages Maven style convention

I want to create a pybuilder project with unit tests and packages. As an example, modified simple python app example, with "helloworld" moved to package "hello".

My first instinct was to match the package structure with "main" and "unittest" sources:

+---src
   +---main
   |   \---python
   |       \---hello
   |               helloworld.py
   |               __init__.py
   |
   \---unittest
       \---python
           \---hello
                   helloworld_tests.py
                   __init__.py

This does not work because of conflicting "hello" package.

BUILD FAILED - 'module' object has no attribute 'helloworld_tests'

I see pybuilder itself just skips the top-level pybuilder package in unittests, but won't do if there are multiple top-level packages.

My second guess would be to create extra top level package for unittests.

\---unittest
    \---python
        \---tests
            |   __init__.py
            \---hello
                    helloworld_tests.py
                    __init__.py

Is there a better solution or established convention how to organize python tests in packages?

like image 244
ketorin Avatar asked Nov 12 '15 08:11

ketorin


1 Answers

Probably nothing really new for the OP, but I just wanted to collect all options that I could come up with in one place:

1) Just append _tests to names of top-level packages

The easiest way to mirror the structure of src/main/python in the src/test/python almost 1:1 would be by simply appending _tests to the names of the top-level packages. For example, if I have only one top-level package rootPkg, then I can add the corresponding rootPkg_tests to the test/ subdirectory:

src
├── main
│   ├── python
│   │   └── rootPkg
│   │       ├── __init__.py
│   │       ├── pkgA
│   │       │   ├── __init__.py
│   │       │   └── modA.py
│   │       └── pkgB
│   │           ├── __init__.py
│   │           └── modB.py
│   └── scripts
│       └── entryPointScript.py
└── test
    └── python
        └── rootPkg_tests
            ├── __init__.py
            ├── pkgA
            │   ├── __init__.py
            │   └── modA_tests.py
            └── pkgB
                ├── __init__.py
                └── modB_tests.py

This seems to work nicely with PyBuilder 0.11.15 and unittest plugin (notice that I've deviated from PyBuilders convention, and put tests in test instead of unittest, you probably shouldn't do this if you intend to use multiple testing frameworks).

2) If there is only one package: do it like PyBuilder

The PyBuilder is itself built with PyBuilder. This is what its source directory looks like (drastically reduced, unnecessary details omitted):

src
├── main
│   ├── python
│   │   └── pybuilder
│   │       ├── __init__.py
│   │       ├── cli.py
│   │       ├── core.py
│   │       └── plugins
│   │           ├── __init__.py
│   │           ├── core_plugin.py
│   │           └── exec_plugin.py
│   └── scripts
│       └── pyb
└── unittest
    └── python
        ├── cli_tests.py
        ├── core_tests.py
        ├── plugins
        │   ├── exec_plugin_tests.py
        │   ├── __init__.py
        │   ├── python
        │   │   ├── core_plugin_tests.py
        │   │   ├── __init__.py

If I understand it correctly, the tree in unittest mirrors the tree in src, but the directory for the top-level package pybuilder is omitted. That's what you have described in your question as first workaround. The drawback is that it doesn't really work if there are multiple top-level packages.

3) Add one additional tests top-level package

That's what you have proposed as a workaround: mirror the tree in main, but wrap everything in an additional tests-package. This works with many top-level packages in /src/main/python and prevents any package name collisions.


I'm not aware of any convention. Upvote one of the comments below if you have an opinion on that matter.

like image 184
Andrey Tyukin Avatar answered Oct 29 '22 17:10

Andrey Tyukin