Boundary value analysis is a type of black box or specification-based testing technique in which tests are performed using the boundary values. It is worth testing boundary values because the input values near the boundary have higher chances of error (this is typically related to the overflow related issues). Whenever we do the testing by boundary value analysis, the tester focuses on, while entering boundary value whether the software is producing correct output or not.

In this example, we will check the majority number of possible cases when exceptions can occur. For tutorial purposes let's write a function called get_triangle_area which returns triangle area calculated from base and height values read from input files (input files are functions' arguments). 


get_triangle_area()
def get_triangle_area(file_base, file_height):
    base = float(open(file_base, 'r').readline())
    height = float(open(file_height, 'r').readline())

    if base not in range(1, 100):
        raise ValueError()
    if height not in range(1, 100):
        raise ValueError()

    return 0.5 * base * height


Before the first test will be written let's think about boundary conditions in the get_triangle_area function. In the list below, we collected seven cases when code execution can end with some errors. 

  1. The input file doesn't exist.
  2. Bad input file extension.
  3. Empty input file.
  4. Bad value type (e.g. base and height can't be strings).
  5. A negative value of base or/and height.
  6. Call function without arguments.
  7. Base or height value bigger than 100 (in get_triangle_area function base and height values should be in the range from 1 to 100).


The next step is to write the tests.

All rules of testing exceptions are explained in 3. Testing exceptions chapter. 


test_get_triangle_area()
def test_get_triangle_area():
    # PROPER RESULT TEST
    assert get_triangle_area("./../resources/base.txt",
                             "./../resources/height.txt") == 25
    # BAD FILENAME
    with pytest.raises(FileNotFoundError):
        get_triangle_area("./../resources/flower.txt",
                          "./../resources/height.txt")
    # EMPTY FILE
    with pytest.raises(ValueError):
        get_triangle_area("./../resources/empty.txt",
                          "./../resources/height.txt")
    # BAD VALUE TYPE
    with pytest.raises(ValueError):
        get_triangle_area("./../resources/string_base.txt",
                          "./../resources/height.txt")
    # NEGATIVE VALUE
    with pytest.raises(ValueError):
        get_triangle_area("./../resources/negative_base.txt",
                          "./../resources/height.txt")
    # BAD FILE EXTENSION
    with pytest.raises(FileNotFoundError):
        get_triangle_area("./../resources/base.txt",
                          "./../resources/height.csv")
    # CALL FUNC WITHOUT ARGUMENTS
    with pytest.raises(TypeError):
        get_triangle_area()

    # BASE EQUAL 1000
    with pytest.raises(ValueError):
        get_triangle_area("./../resources/mega_base.txt",
                          "./../resources/height.txt")


Let's run the test_get_triangle_area and inspect the result.


As we suspected all tests passed. It means that  get_triangle_area() returns proper results and whenever something goes wrong proper exceptions would occur. 





  • No labels