Use pytest to run unittests.

main
Ben Niemann 2021-10-26 18:12:38 +02:00
parent 0163ef5f3b
commit f3afb63253
5 changed files with 102 additions and 41 deletions

View File

@ -1,6 +1,7 @@
((nil . (
; Projetile
(projectile-project-test-cmd . "./waf test")
(projectile-project-test-cmd . "nix-shell --run './waf test'")
(projectile-project-compilation-cmd . "nix-shell --run './waf build'")
(pyvenv-workon . "noisicaa")

View File

@ -34,28 +34,34 @@
ffmpeg
}:
let
# pytest-cpp: Use pytest's runner to discover and execute C++ tests
# https://github.com/pytest-dev/pytest-cpp
pytest-cpp = { fetchPypi, buildPythonPackage, setuptools_scm, pytest, colorama }: buildPythonPackage rec {
pname = "pytest-cpp";
version = "2.0.0";
src = fetchPypi {
inherit pname version;
sha256 = "sha256:1ks3l94iqn5509bp0h1xcv19z34agh94xac6c00snjggplzz5jvc";
};
nativeBuildInputs = [ setuptools_scm ];
buildInputs = [
pytest
colorama
];
pipy-pkg = pp: { pname, version, sha256, deps ? [] }: pp.buildPythonPackage rec {
inherit pname version;
src = pp.fetchPypi { inherit pname version sha256; };
nativeBuildInputs = [ pp.setuptools_scm ];
propagatedBuildInputs = deps;
};
python = python3.withPackages (pp: [
pp.pytest
(pp.callPackage pytest-cpp {})
]);
python = let
packageOverrides = self: pp: rec {
# pytest: The pytest framework makes it easy to write small tests, yet scales to support complex functional testing.
# https://github.com/pytest-dev/pytest
pytest = pipy-pkg pp {
pname = "pytest";
version = "6.2.5";
sha256 = "sha256:12cyi0lnyaq8sdqfnqlppd76gkw6zcg10gyih5knx9v611l3c6qk";
deps = with pp; [ attrs iniconfig packaging pluggy py atomicwrites colorama importlib-metadata ];
};
# pytest-cpp: Use pytest's runner to discover and execute C++ tests
# https://github.com/pytest-dev/pytest-cpp
pytest_cpp = pipy-pkg pp {
pname = "pytest-cpp";
version = "2.0.0";
sha256 = "sha256:1ks3l94iqn5509bp0h1xcv19z34agh94xac6c00snjggplzz5jvc";
deps = with pp; [ pytest colorama ];
};
};
in python3.override {inherit packageOverrides;};
# gitignoreSource: Nix functions for filtering local git sources
# https://github.com/hercules-ci/gitignore.nix
@ -122,7 +128,10 @@ in stdenv.mkDerivation {
src = gitignoreSource ./.;
nativeBuildInputs = [
python
(python.withPackages (ps: with ps; [
pytest
pytest_cpp
]))
lcov
wafHook
pkg-config

View File

@ -43,10 +43,11 @@ def build(ctx):
use=['JACK', 'PROTOBUF', 'SWRESAMPLE', 'AVUTIL', 'FLATBUFFERS', 'GRPC'],
)
for test in ctx.path.ant_glob('*_test.cpp'):
ctx.program(
features='test',
target=test.change_ext(''),
source=[test],
use=['GTEST', 'noisicaa-core'],
)
if ctx.cmd == 'test':
with ctx.group(ctx.GRP_BUILD_TESTS):
for test in ctx.path.ant_glob('*_test.cpp'):
ctx.program(
target=test.change_ext(''),
source=[test],
use=['GTEST', 'noisicaa-core'],
)

3
pytest.ini Normal file
View File

@ -0,0 +1,3 @@
[pytest]
console_output_style = progress
testpaths = build

71
wscript
View File

@ -18,9 +18,11 @@
#
# @end:license
import contextlib
import fnmatch
import os.path
import subprocess
from waflib.Build import BuildContext
from waflib.Configure import conf
from waflib.Errors import BuildError
from waflib import Logs
@ -29,6 +31,9 @@ from waflib import Utils
top = '.'
out = 'build'
# Properly format command lines when using -v
os.environ['WAF_CMD_FORMAT'] = 'string'
@conf
def pkg_config(ctx, store, package, minver):
@ -41,7 +46,6 @@ def pkg_config(ctx, store, package, minver):
def options(ctx):
ctx.load('compiler_cxx')
ctx.load('waf_unit_test')
grp = ctx.add_option_group('Test options')
grp.add_option(
@ -52,10 +56,15 @@ def options(ctx):
def configure(ctx):
ctx.load('compiler_cxx')
ctx.load('waf_unit_test')
ctx.load('python')
ctx.load('build_utils.waf.proto', tooldir='.')
ctx.load('build_utils.waf.flatbuffers', tooldir='.')
ctx.env.append_value('CXXFLAGS', ['-g', '-O2', '-std=c++17', '-Wall'])
ctx.env.append_value('CFLAGS', ['-g', '-O2'])
ctx.env.append_value('LINKFLAGS', ['-lrt'])
ctx.env.append_value('INCLUDES', [ctx.srcnode.abspath(), ctx.bldnode.abspath()])
ctx.check_cfg(atleast_pkgconfig_version='0.29')
ctx.pkg_config('GTEST', 'gtest', '1.10')
ctx.pkg_config('JACK', 'jack', '1.9')
@ -65,10 +74,8 @@ def configure(ctx):
ctx.pkg_config('SWRESAMPLE', 'libswresample', '1.2')
ctx.pkg_config('AVUTIL', 'libavutil', '54')
ctx.env.append_value('CXXFLAGS', ['-g', '-O2', '-std=c++17', '-Wall'])
ctx.env.append_value('CFLAGS', ['-g', '-O2'])
ctx.env.append_value('LINKFLAGS', ['-lrt'])
ctx.env.append_value('INCLUDES', [ctx.srcnode.abspath(), ctx.bldnode.abspath()])
ctx.check_python_module('pytest', condition="ver > num(6, 2, 0)")
ctx.check_python_module('pytest_cpp') # has no __version__
if ctx.options.coverage:
ctx.start_msg("Enable code coverage analysis")
@ -86,12 +93,18 @@ def configure(ctx):
ctx.env['ENABLE_COVERAGE'] = False
def clear_coverage_data(ctx):
if not ctx.env['ENABLE_COVERAGE']:
return
for dirpath, dirnames, filenames in os.walk(ctx.out_dir):
for filename in filenames:
if fnmatch.fnmatch(filename, '*.gcda'):
os.unlink(os.path.join(dirpath, filename))
def coverage_report(ctx):
if not ctx.env['ENABLE_COVERAGE']:
return
report_dir = os.path.join(ctx.out_dir, 'coverage')
os.makedirs(report_dir, exist_ok=True)
@ -100,6 +113,9 @@ def coverage_report(ctx):
ctx.env.LCOV[0],
'--gcov-tool=' + ctx.env.GCOV[0],
'--exclude=*_test.cpp',
'--exclude=*_generated.h',
'--exclude=*.fb.cc',
'--exclude=*.fb.h',
'--exclude=*.pb.cc',
'--exclude=*.pb.h',
'--no-external',
@ -135,14 +151,45 @@ def coverage_report(ctx):
Logs.info("%sCoverage report: %sfile://%s/index.html", Logs.get_color('BLUE'), Logs.get_color('PINK'), report_dir)
@conf
@contextlib.contextmanager
def group(ctx, grp):
old_grp = ctx.current_group
ctx.set_group(grp)
try:
yield
finally:
ctx.set_group(old_grp)
def run_tests(ctx):
import pytest
os.environ["COLUMNS"] = "80"
pytest.main(['-v'])
coverage_report(ctx)
def build(ctx):
if ctx.env['ENABLE_COVERAGE'] and not ctx.options.no_tests:
ctx.options.all_tests = True
ctx.add_pre_fun(clear_coverage_data)
ctx.add_post_fun(coverage_report)
ctx.GRP_BUILD_TOOLS = 'build:tools'
ctx.GRP_BUILD_MAIN = 'build:main'
ctx.GRP_BUILD_TESTS = 'build:tests'
ctx.GRP_RUN_TESTS = 'run:tests'
ctx.add_group(ctx.GRP_BUILD_TOOLS)
ctx.add_group(ctx.GRP_BUILD_MAIN)
ctx.add_group(ctx.GRP_BUILD_TESTS)
ctx.set_group(ctx.GRP_BUILD_MAIN)
ctx(rule='touch ${TGT}', target='.nobackup')
ctx.recurse('noisicaa')
from waflib.Tools import waf_unit_test
ctx.add_post_fun(waf_unit_test.summary)
if ctx.cmd == 'test':
ctx.add_pre_fun(clear_coverage_data)
ctx.add_post_fun(run_tests)
class TestContext(BuildContext):
"""run unittests"""
cmd = 'test'