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, equationSolver.py néven!

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 application.py!

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 test_EquationSolver.py néven!

# 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:

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 pylint modulra:

pip install pylint

A linter kódja:

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!

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:

""" 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 .pylintrc módosítja a linter működését:

[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:

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

score=%d 10.0