Skip to content

Testing plots

Ainur Gimadeev edited this page Oct 13, 2022 · 5 revisions

Introduction

This wiki page will describe the process of testing plots in python using hs-test-python library. We will describe only plotting related features of the library. The basics of the testing process can be found in the writing tests section.

How it works

The testing library supports the following python data visualization libraries:

  • matplotlib
  • pandas
  • seaborn

After running the tests, the hs-test-python library will intercept the creation of plots, and you will be able to access these plots' data.

Essential classes

Drawing

The class that represents a plot that is plotted using data visualization libraries. It has the following fields:

  • library - describes the name of the library that have been used to plot a data.
  • type - is a type of plot.
  • data - the instance of the DrawingData class that has x and y fields with np.ndarray types. These fields will store the initial data that was visualized.
  • kwargs - keyword arguments that were used to visualize a data.

PlottingTest

The main class that is used to test plots is PlottingTest class. It can be imported from hstest module:

from hstest import PlottingTest

You should write your test case inside a class that inherits the PlottingTest class.

It has the following methods:

  • all_figures() - returns the list of all Drawing objects created after execution of the tested program.
  • new_figures() - returns the list of Drawing objects that were created before calling this method.

Supported plot types

For now it supports the following plot types:

  • histplot (matplotlib, pandas, seaborn)
  • barplot (matplotlib, pandas, seaborn)
  • horizontal barplot (the same as barplot)
  • pieplot (matplotlib, pandas)

Examples

Example 1. Single plot

Let's imagine the program draws a histogram using matplotlib library using the following code snippet:

fig, ax = plt.subplots(figsize=(5, 5))

ax.hist([1, 2, 2, 2, 3, 3, 4, 5, 4, 4])

The result of the execution will be the following plot:

image

You can get the Drawing object in the tests in the following way:

from hstest import PlottingTest, TestedProgram, correct, wrong, dynamic_test


class TestMatplotlibHist(PlottingTest):
    @dynamic_test
    def test(self):
        program = TestedProgram()
        program.start()

        drawings = self.all_figures()
        if len(drawings) == 0:
            return wrong("Looks like your program didn't visualize any data!")

        drawing = drawings[0]

        if drawing.type != 'hist':
            return wrong("Your program should plot a histogram!")

        if drawing.library != 'matplotlib':
            return wrong("You should plot a histogram using matplotlib library!")

        # drawing.data.x is a np.ndarray, so you should convert it into list before comparing with another list
        if list(drawing.data.x) != [1, 2, 2, 2, 3, 3, 4, 5, 4, 4]: 
            return wrong('The histogram was plotted using wrong data!')

        return correct()

Example 2. Multiple plots

If the program draws multiple plots, the Drawing object will be created for each of them.

Program that draws multiple plots:

fig, ax = plt.subplots()

ax.hist(np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]))
plt.show()

The result output:

image

You can test it this way:

from hstest import PlottingTest, TestedProgram, correct, wrong, dynamic_test


class TestMultiplePlots(PlottingTest):
    @dynamic_test
    def test(self):
        program = TestedProgram()
        program.start()

        drawings = self.all_figures()
        if len(drawings) == 2:
            return wrong(f"Expected 2 plots to be drawn\n"
                         f"Found: {len(drawings)}")

        return correct()