Unit tesztek ============= Példa ---------------------------- Készítsünk egy függvényt, amely egy másodfokú egyenlet gyökeit adja vissza! A függvény neve secondDegreeEquationSolver legyen, és kerüljön egy önálló fájlba, :file:`equationSolver.py` néven! .. code-block:: console class equationSolver(): def secondDegreeEquationSolver(self, a, b, c): if type(a) not in [int, float] or type(b) not in [int, float] or type(c) not in [int, float]: raise TypeError('Int or float only.') d = (b * b) - (4 * a * c) if d < 0: return None, None sqrtd = d ** 0.5 return (-b + sqrtd) / 2 / a, (-b - sqrtd) / 2 / a Készíts egy programot, mely erre a alapozva konkrét egyenletek megoldásait adja meg! A program neve legyen :file:`application.py`! .. code-block:: console from equationSolver import * def solveTheProblem(a, b, c): e = equationSolver() x1, x2 = e.secondDegreeEquationSolver(a, b, c) # pylint: disable=invalid-name print ("%dx^2 + %dx + %d = 0" % (a,b,c)) if (x1 == None) and (x2 == None): print("There are no solutions.") if (x1 == x2): print("One solution has been found: %d", (x1)) else: print("Two different soultions are exist: x1=%f, x2=%f" % (x1, x2)) print("------------") solveTheProblem(1, 2, 8) solveTheProblem(1, -14, 49) solveTheProblem(1, 6, 8) solveTheProblem(1, 6, 'alma') Készítsünk egy tesztelést végző programot :file:`test_EquationSolver.py` néven! .. code-block:: console # https://docs.python.org/3/library/unittest.html import unittest from equationSolver import * class testEquationSolverClass(unittest.TestCase): @classmethod def setUp(self): print("setUp test class") self.tst = equationSolver() @classmethod def tearDown(self): print("tearDown.") def test_secondDegreeEquation_case_for_solutions(self): print("running test 1") self.assertEqual(self.tst.secondDegreeEquationSolver(1, 2, 8), (None, None), msg="D<0 hiba") print("running test 2") self.assertEqual(self.tst.secondDegreeEquationSolver(1, -14, 49), (7, 7), msg="D=1 hiba") print("running test 3") self.assertEqual(self.tst.secondDegreeEquationSolver(1, 6, 8), (-2, -4), msg="D=2 hiba") def test_secondDegreeEquation_case_TypeError(self): print("running TypeError test") with self.assertRaises(TypeError): result = self.tst.secondDegreeEquationSolver(True, 2, 4) if __name__ == '__main__': unittest.main() Futtassuk: .. code-block:: console koczka@columbo:~/python$ python3 test_EquationSolver.py setUp test class running TypeError test tearDown. .setUp test class running test 1 running test 2 running test 3 tearDown. . ---------------------------------------------------------------------- Ran 2 tests in 0.002s OK Elemezzük a programot stilisztikai szempontból! Ehhez szükségünk lesz a :envvar:`pylint` modulra: .. code-block:: console pip install pylint A linter kódja: .. code-block:: console import sys from pylint import lint THRESHOLD = 8 run = lint.Run(["application.py"], do_exit=False) score = run.linter.stats.global_note # score = lint.Run(["application.py"], do_exit=False).linter.stats.global_note print("score=%d", score) if score < THRESHOLD: print("Linter failed: Score < threshold value") sys.exit(1) sys.exit(0) Lássuk az elemzést! .. code-block:: console koczka@columbo:~/python$ python3 lint.py ************* Module application application.py:9:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) application.py:1:0: C0114: Missing module docstring (missing-module-docstring) application.py:1:0: W0401: Wildcard import equationSolver (wildcard-import) application.py:3:0: C0116: Missing function or method docstring (missing-function-docstring) application.py:3:0: C0103: Function name "solveTheProblem" doesn't conform to snake_case naming style (invalid-name) application.py:3:20: C0103: Argument name "a" doesn't conform to snake_case naming style (invalid-name) application.py:3:23: C0103: Argument name "b" doesn't conform to snake_case naming style (invalid-name) application.py:3:26: C0103: Argument name "c" doesn't conform to snake_case naming style (invalid-name) application.py:4:4: C0103: Variable name "e" doesn't conform to snake_case naming style (invalid-name) application.py:5:4: C0103: Variable name "x1" doesn't conform to snake_case naming style (invalid-name) application.py:5:8: C0103: Variable name "x2" doesn't conform to snake_case naming style (invalid-name) application.py:6:11: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) application.py:7:8: C0121: Comparison 'x1 == None' should be 'x1 is None' (singleton-comparison) application.py:7:25: C0121: Comparison 'x2 == None' should be 'x2 is None' (singleton-comparison) application.py:12:14: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) ------------------------------------------------------------------ Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00) score=%d 0 Linter failed: Score < threshold value A linter az alábbi javítások mellett éri el a 10 pontot: .. code-block:: console """ Másodfokú egyenlet megoldása""" from equationSolver import equationSolver def solve_the_problem(var_a, var_b, var_c): """ A függvény""" var_e = equationSolver() var_x1, var_x2 = var_e.secondDegreeEquationSolver(var_a, var_b, var_c) print ('%dx^2 + %dx + %d = 0' % (var_a, var_b, var_c)) if (var_x1 is None) and (var_x2 is None): print('Nincs megoldás') if var_x1==var_x2: print('Egy megoldás: %d', (var_x1)) else: print('Két megoldás: x1=%f, x2=%f' % (var_x1, var_x2)) print("------------") solve_the_problem(1, 2, 8) solve_the_problem(1, -14, 49) solve_the_problem(1, 6, 8) # solveTheProblem(1, 6, 'alma') A :file:`.pylintrc` módosítja a linter működését: .. code-block:: console [MASTER] disable=consider-using-f-string argument-naming-style=camelCase attr-naming-style=camelCase class-attribute-naming-style=camelCase class-const-naming-style=camelCase class-naming-style=camelCase const-naming-style=camelCase function-naming-style=camelCase inlinevar-naming-style=camelCase method-naming-style=camelCase module-naming-style=camelCase variable-naming-style=camelCase Ezzel a program 10 pontot ér el: .. code-block:: console -------------------------------------------------------------------- Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) score=%d 10.0