t
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
from ex2_dictionary import calculate_price
|
||||
from util import eidp_test, has_annotations, imported_modules_of, has_no_annotations
|
||||
from util import *
|
||||
import pytest
|
||||
import sys
|
||||
import argparse
|
||||
from enum import Enum
|
||||
from copy import deepcopy
|
||||
|
||||
@ -72,7 +74,7 @@ def test_typeannotation_by_amount():
|
||||
|
||||
@pytest.mark.dependency(depends=[Task.A])
|
||||
@pytest.mark.timeout(10)
|
||||
@eidp_test("es wird nicht geschaut ob ein ein Produkt in `articles` ist", -2)
|
||||
@eidp_test("nicht überprüft ob Produkte in `articles` enthalten", -2)
|
||||
def test_article_not_in_articles():
|
||||
articles = {'Coke': 200}
|
||||
basket = {'Vitamine R': 1}
|
||||
@ -98,11 +100,16 @@ def test_price_calc():
|
||||
articles = {'Coke': 200, 'Eis': 350}
|
||||
basket = {'Coke': 2, 'Eis': 3}
|
||||
assert abs(calculate_price(articles, basket) - 14.5) < EPS
|
||||
articles_dict = {"apples": 100, "oranges": 100,
|
||||
"lemons": 200, "avocado": 500}
|
||||
cart_dict = {"apples": 2, "oranges": 2, "lemons": 1, "bananas": 5}
|
||||
|
||||
assert abs(calculate_price(articles_dict, cart_dict) - 6) < EPS
|
||||
|
||||
|
||||
@pytest.mark.dependency(depends=[Task.A])
|
||||
@pytest.mark.timeout(10)
|
||||
@eidp_test("`articles`/`cart` wird veraendert", -2)
|
||||
@eidp_test("`articles`/`cart` wird verwendet", -2)
|
||||
def test_sideeffectss():
|
||||
a = {'Coke': 200, 'Eis': 350}
|
||||
b = {'Coke': 2, 'Eis': 3}
|
||||
@ -110,5 +117,74 @@ def test_sideeffectss():
|
||||
assert a == a2 and b2 == b
|
||||
|
||||
|
||||
@pytest.mark.dependency(depends=[Task.B])
|
||||
@pytest.mark.timeout(10)
|
||||
@eidp_test("nicht überprüft ob Produkte in `articles` enthalten", -2)
|
||||
def test_article_not_in_articles_by_amount():
|
||||
from ex2_dictionary import by_amount
|
||||
articles_dict = {"apples_ex": 100, "oranges_ex": 100,
|
||||
"lemons": 200, "avocado_ex": 500}
|
||||
cart_dict = {"apples": 2, "oranges": 2, "lemons": 1, "bananas": 5}
|
||||
|
||||
assert by_amount(articles_dict, cart_dict) == {1: ['lemons']}
|
||||
|
||||
|
||||
@pytest.mark.dependency(depends=[Task.B])
|
||||
@pytest.mark.timeout(10)
|
||||
@eidp_test("`by_amount` wird nicht korrekt berechnet", -2)
|
||||
def test_by_amount():
|
||||
from ex2_dictionary import by_amount
|
||||
articles_dict = {"apples": 100, "oranges": 100,
|
||||
"lemons": 200, "avocado": 500}
|
||||
cart_dict = {"apples": 2, "oranges": 2, "lemons": 1, "bananas": 5}
|
||||
|
||||
assert by_amount(articles_dict, cart_dict) == {
|
||||
2: ['apples', 'oranges'], 1: ['lemons']}
|
||||
|
||||
|
||||
@pytest.mark.dependency(depends=[Task.B])
|
||||
@pytest.mark.timeout(10)
|
||||
@eidp_test("es wird kein neues Dictionary erstellt", -4)
|
||||
def test_sideeffects_by_amount():
|
||||
from ex2_dictionary import by_amount
|
||||
a = {"apples": 100, "oranges": 100,
|
||||
"lemons": 200, "avocado": 500}
|
||||
b = {"apples": 2, "oranges": 2, "lemons": 1, "bananas": 5}
|
||||
|
||||
r = by_amount(a2 := deepcopy(a), b2 := deepcopy(b)) == {
|
||||
2: ['apples', 'oranges'], 1: ['lemons']}
|
||||
assert a2 == a and b2 == b and r is not a and r is not b
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
verbose, testing, force = tuple(parse_args(sys.argv).values())
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='ex2_dictionary.py test',
|
||||
description='testing for eidp 2023 ex2 dictionaries',
|
||||
)
|
||||
parser.add_argument('-v', '--verbose',
|
||||
help="don't print out test output", action="store_true")
|
||||
parser.add_argument(
|
||||
'-t', '--test_only', help='only test without writing readme', action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
# print(options)
|
||||
# print(f'verbose := {verbose}, backup := {backup}')
|
||||
|
||||
collector = ResultsCollector()
|
||||
pytest.main(['test_dictionary.py', '-vv', '-s'], plugins=[collector])
|
||||
|
||||
readme_template = []
|
||||
passed, failed, skipped = collector.get_results()
|
||||
|
||||
if args.verbose:
|
||||
print(f"passed := {passed}")
|
||||
print(f"failed := {failed}")
|
||||
print(f"skipped := {skipped}")
|
||||
|
||||
if not args.test_only:
|
||||
tests = dict([(name, f) for name, f in vars() if callable(
|
||||
f) and hasattr(f, "is_test")])
|
||||
passed_tests = list(map(lambda m: m[1], filter(
|
||||
lambda m: m[0] in passed, tests)))
|
||||
print(passed_tests)
|
||||
|
63
src/util.py
63
src/util.py
@ -1,6 +1,8 @@
|
||||
from typing import Callable, Any, TypeAliasType, Iterator
|
||||
from types import ModuleType
|
||||
import inspect
|
||||
import pytest
|
||||
import time
|
||||
|
||||
|
||||
def has_annotations(f: Callable, param_types: list[object], return_type: object = None) -> bool:
|
||||
@ -34,6 +36,61 @@ def eidp_test(message: str, minus_points: float) -> Callable[[Callable[..., Any]
|
||||
return wrapper
|
||||
|
||||
|
||||
def get_tests(module: ModuleType) -> dict[str, Callable[..., Any]]:
|
||||
return dict([(name, f) for name, f in module.__dict__
|
||||
if callable(f) and hasattr(f, "is_test")])
|
||||
class ResultsCollector:
|
||||
def __init__(self):
|
||||
self.reports = []
|
||||
self.collected = 0
|
||||
self.exitcode = 0
|
||||
self.passed = 0
|
||||
self.failed = 0
|
||||
self.xfailed = 0
|
||||
self.skipped = 0
|
||||
self.total_duration = 0
|
||||
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_runtest_makereport(self, item, call):
|
||||
outcome = yield
|
||||
report = outcome.get_result()
|
||||
if report.when == 'call':
|
||||
self.reports.append(report)
|
||||
|
||||
def pytest_collection_modifyitems(self, items):
|
||||
self.collected = len(items)
|
||||
|
||||
def pytest_terminal_summary(self, terminalreporter, exitstatus):
|
||||
self.passed = len(terminalreporter.stats.get('passed', []))
|
||||
self.failed = len(terminalreporter.stats.get('failed', []))
|
||||
self.xfailed = len(terminalreporter.stats.get('xfailed', []))
|
||||
self.skipped = len(terminalreporter.stats.get('skipped', []))
|
||||
self.total_duration = time.time() - terminalreporter._sessionstarttime
|
||||
|
||||
def get_results(self) -> tuple[list[str], list[str], list[str]]:
|
||||
passed = []
|
||||
failed = []
|
||||
skipped = []
|
||||
|
||||
for report in self.reports:
|
||||
if report.outcome == 'passed':
|
||||
passed.append(report.nodeid.split('::')[-1])
|
||||
elif report.outcome == 'failed':
|
||||
failed.append(report.nodeid.split('::')[-1])
|
||||
elif report.outcome == 'skipped':
|
||||
skipped.append(report.nodeid.split('::')[-1])
|
||||
|
||||
return passed, failed, skipped
|
||||
|
||||
|
||||
def parse_args(args: list[str]) -> dict[str, bool]:
|
||||
arguments = args[1:]
|
||||
retval = {'verbose': False, 'test': False, 'force': False}
|
||||
for argument in arguments:
|
||||
_args = argument[1:] if argument[0] == '-' else argument
|
||||
for arg in _args:
|
||||
match arg:
|
||||
case 'v':
|
||||
retval['verbose'] = True
|
||||
case 't':
|
||||
retval['test'] = True
|
||||
case 'f':
|
||||
retval['force'] = True
|
||||
return retval
|
||||
|
Reference in New Issue
Block a user