[tests] moved cli tests to one file with incremental tests (exits if one fails)

This commit is contained in:
Maxime Alves LIRMM 2020-08-05 11:10:14 +02:00
parent d47f735828
commit 048d06de37
4 changed files with 168 additions and 171 deletions

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python3
import os
import subprocess
import pytest
from click.testing import CliRunner
from halfapi import __version__
from halfapi.cli import cli
from configparser import ConfigParser
projname = os.environ.get('PROJ','tmp_api')
@pytest.fixture
def dropdb():
p = subprocess.Popen(['dropdb', f'halfapi_{projname}'])
p.wait()
yield
p = subprocess.Popen(['dropdb', f'halfapi_{projname}'])
p.wait()
def test_init_project(dropdb):
runner = CliRunner()
cp = ConfigParser()
with runner.isolated_filesystem():
env = {
'HALFORM_CONF_DIR': os.environ.get('HALFORM_CONF_DIR', os.getcwd()),
'HALFAPI_CONF_DIR': os.environ.get('HALFAPI_CONF_DIR', os.getcwd()),
}
res = runner.invoke(cli, ['init-project', projname], env=env)
try:
assert os.path.isdir(projname)
assert os.path.isdir(os.path.join(projname, '.halfapi'))
# .halfapi/config check
assert os.path.isfile(os.path.join(projname, '.halfapi', 'config'))
cp.read(os.path.join(projname, '.halfapi', 'config'))
assert cp.has_section('project')
assert cp.has_option('project', 'name')
assert cp.get('project', 'name') == projname
assert cp.get('project', 'halfapi_version') == __version__
# .halfapi/domains check
assert os.path.isfile(os.path.join(projname, '.halfapi', 'domains'))
cp.read(os.path.join(projname, '.halfapi', 'domains'))
assert cp.has_section('domains')
except AssertionError:
subprocess.run(['tree', '-a', os.getcwd()])
assert res.exit_code == 0
assert res.exception is None

53
tests/conftest.py Normal file
View File

@ -0,0 +1,53 @@
# content of conftest.py
from typing import Dict, Tuple
import pytest
# store history of failures per test class name and per index in parametrize (if
# parametrize used)
_test_failed_incremental: Dict[str, Dict[Tuple[int, ...], str]] = {}
def pytest_runtest_makereport(item, call):
if "incremental" in item.keywords:
# incremental marker is used
if call.excinfo is not None:
# the test has failed
# retrieve the class name of the test
cls_name = str(item.cls)
# retrieve the index of the test (if parametrize is used in
# combination with incremental)
parametrize_index = (
tuple(item.callspec.indices.values())
if hasattr(item, "callspec")
else ()
)
# retrieve the name of the test function
test_name = item.originalname or item.name
# store in _test_failed_incremental the original name of the failed
# test
_test_failed_incremental.setdefault(cls_name, {}).setdefault(
parametrize_index, test_name
)
def pytest_runtest_setup(item):
if "incremental" in item.keywords:
# retrieve the class name of the test
cls_name = str(item.cls)
# check if a previous test has failed for this class
if cls_name in _test_failed_incremental:
# retrieve the index of the test (if parametrize is used in
# combination with incremental)
parametrize_index = (
tuple(item.callspec.indices.values())
if hasattr(item, "callspec")
else ()
)
# retrieve the name of the first test function to fail for this
# class name and index
test_name = _test_failed_incremental[cls_name].get(parametrize_index, None)
# if name found, test has failed for the combination of class name &
# test name
if test_name is not None:
pytest.xfail("previous test failed ({})".format(test_name))

View File

@ -1,42 +1,134 @@
#!/usr/bin/env python3
import os
import subprocess
import pytest
from click.testing import CliRunner
from configparser import ConfigParser
from halfapi import __version__
from halfapi.cli import cli
PROJNAME = os.environ.get('PROJ','tmp_api')
@pytest.fixture
def runner():
return CliRunner()
def test_cli(runner):
# Wrong command
with runner.isolated_filesystem():
r = runner.invoke(cli, ['foobar'])
@pytest.fixture
def dropdb():
p = subprocess.Popen(['dropdb', f'halfapi_{PROJNAME}'])
p.wait()
yield
p = subprocess.Popen(['dropdb', f'halfapi_{PROJNAME}'])
p.wait()
@pytest.mark.incremental
class TestCli():
def test_options(self, runner, dropdb):
# Wrong command
with runner.isolated_filesystem():
r = runner.invoke(cli, ['foobar'])
assert r.exit_code == 2
# Test existing commands
with runner.isolated_filesystem():
r = runner.invoke(cli, ['--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['--version'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['init-project', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['run', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['domain', '--help'])
assert r.exit_code == 0
def test_init_project_fail(self, runner, dropdb):
# Missing argument (project)
testproject = 'testproject'
r = runner.invoke(cli, ['init-project'])
assert r.exit_code == 2
# Test existing commands
with runner.isolated_filesystem():
r = runner.invoke(cli, ['--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
# Fail : Wrong project name
r = runner.invoke(cli, ['init-project', 'test*-project'])
assert r.exit_code == 1
with runner.isolated_filesystem():
r = runner.invoke(cli, ['--version'])
assert r.exit_code == 0
with runner.isolated_filesystem():
# Fail : Already existing folder
os.mkdir(testproject)
r = runner.invoke(cli, ['init-project', testproject])
assert r.exit_code == 1
with runner.isolated_filesystem():
r = runner.invoke(cli, ['init-project', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
# Fail : Already existing nod
os.mknod(testproject)
r = runner.invoke(cli, ['init-project', testproject])
assert r.exit_code == 1
with runner.isolated_filesystem():
r = runner.invoke(cli, ['run', '--help'])
assert r.exit_code == 0
def test_init_project(self, runner, dropdb):
cp = ConfigParser()
with runner.isolated_filesystem():
env = {
'HALFORM_CONF_DIR': os.environ.get('HALFORM_CONF_DIR', os.getcwd()),
'HALFAPI_CONF_DIR': os.environ.get('HALFAPI_CONF_DIR', os.getcwd()),
}
with runner.isolated_filesystem():
r = runner.invoke(cli, ['domain', '--help'])
assert r.exit_code == 0
res = runner.invoke(cli, ['init-project', PROJNAME], env=env)
try:
assert os.path.isdir(PROJNAME)
assert os.path.isdir(os.path.join(PROJNAME, '.halfapi'))
with runner.isolated_filesystem():
r = runner.invoke(cli, ['routes', '--help'])
assert r.exit_code == 0
# .halfapi/config check
assert os.path.isfile(os.path.join(PROJNAME, '.halfapi', 'config'))
cp.read(os.path.join(PROJNAME, '.halfapi', 'config'))
assert cp.has_section('project')
assert cp.has_option('project', 'name')
assert cp.get('project', 'name') == PROJNAME
assert cp.get('project', 'halfapi_version') == __version__
# .halfapi/domains check
assert os.path.isfile(os.path.join(PROJNAME, '.halfapi', 'domains'))
cp.read(os.path.join(PROJNAME, '.halfapi', 'domains'))
assert cp.has_section('domains')
except AssertionError:
subprocess.run(['tree', '-a', os.getcwd()])
assert res.exit_code == 0
assert res.exception is None
def test_domain_commands(self, runner, dropdb):
with runner.isolated_filesystem():
res = runner.invoke(cli, ['domain', 'foobar'])
assert res.exit_code == 2
with runner.isolated_filesystem():
res = runner.invoke(cli, ['domain', 'create', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
res = runner.invoke(cli, ['domain', 'read', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
res = runner.invoke(cli, ['domain', 'update', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
res = runner.invoke(cli, ['domain', 'delete', '--help'])
assert r.exit_code == 0

View File

@ -1,92 +0,0 @@
#!/usr/bin/env python3
import os
import pytest
from click.testing import CliRunner
from halfapi import __version__
from halfapi.cli import cli
from configparser import ConfigParser
@pytest.fixture
def runner():
return CliRunner()
@pytest.mark.skip
def test_init_project(runner):
# Missing argument (project)
testproject = 'testproject'
r = runner.invoke(cli, ['init-project'])
assert r.exit_code == 2
with runner.isolated_filesystem():
# Fail : Wrong project name
r = runner.invoke(cli, ['init-project', 'test*-project'])
assert r.exit_code == 1
with runner.isolated_filesystem():
# Fail : Already existing folder
os.mkdir(testproject)
r = runner.invoke(cli, ['init-project', testproject])
assert r.exit_code == 1
with runner.isolated_filesystem():
# Fail : Already existing nod
os.mknod(testproject)
r = runner.invoke(cli, ['init-project', testproject])
assert r.exit_code == 1
with runner.isolated_filesystem():
# Fail : No rights in /etc
r = runner.invoke(cli, ['init-project', testproject], env={
'HALFORM_CONF_DIR':'/etc/half_orm'
})
assert r.exit_code == 1
assert type(r.exception) is PermissionError
testproject = 'testproject'
import subprocess
@pytest.fixture
def dropdb():
subprocess.run(['/usr/bin/dropdb', f'halfapi_{testproject}'])
yield
return subprocess.run(['/usr/bin/dropdb', f'halfapi_{testproject}'])
def test_init_project_success(runner, dropdb):
with runner.isolated_filesystem():
# Success : New repo
r = runner.invoke(cli, ['init-project', testproject])
assert r.exit_code == 0
assert os.path.isdir(testproject)
assert os.path.isdir(f'{testproject}/.git')
assert os.path.isdir(f'{testproject}/.halfapi')
domains_file = 'testproject/.halfapi/domains'
assert os.path.isfile(domains_file)
conf_file = 'testproject/.halfapi/config'
assert os.path.isfile(conf_file)
config = ConfigParser()
config.read([conf_file])
assert config.has_section('project')
assert config.has_option('project', 'name')
assert config.get('project', 'name') == testproject
assert config.get('project', 'halfapi_version') == __version__
@pytest.mark.skip
def test_init_project_clone_success(runner):
with runner.isolated_filesystem():
# Success : Cloned repo
import pygit2
pygit2.init_repository('testproject.git', bare=True)
assert os.path.isdir('testproject.git')
r = runner.invoke(cli, [
'init-project', testproject, '--repo',
f'./{testproject}.git'])
assert r.exit_code == 0
assert os.path.isdir(testproject)
assert os.path.isdir('testproject/.git')