I am testing out my module using the unittest
library. This includes plotting some graphs using the matplotlib
library. The issue at the moment is that the testing pauses every time a graph is plotted, and it only resumes after I close the graph. How can I avoid this?

- 4,607
- 12
- 44
- 91
3 Answers
I will model my answer after the simple example code from the matplotlib tutorial: http://matplotlib.org/users/pyplot_tutorial.html
Let's assume we have the following module, plot_graph.py
to be tested:
import matplotlib.pyplot as plt
def func_plot():
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()
if __name__ == "__main__":
func_plot()
The calls to show
can be patched as follows:
from plot_graph import func_plot
from unittest.mock import patch
@patch("plot_graph.plt.show")
def test_plot(mock_show):
assert func_plot() == None
As you can see, you should patch the calls to pyplot.show()
. You can find more about patching and mocking in the docs: https://docs.python.org/3/library/unittest.mock.html.
Usually the section about where to patch is really useful: https://docs.python.org/3/library/unittest.mock.html#where-to-patch
Finally there are similar question already on the site: How to run nosetests without showing of my matplotlib's graph?

- 1
- 1

- 2,504
- 16
- 21
Don't call pyplot.show()
if this is done in the tests. Also the documentation suggests using an experimental block=False
keyword argument to the show
function.

- 190
- 8
-
`pyplot.show()` is called in one of my modules, not in the tests. `block=False` doesn't work for me. I think its deprecated. – bluprince13 Mar 24 '17 at 11:27
-
Maybe calling pyplot.close("all") from your tests could do the trick. – Lukisn Mar 25 '17 at 16:17
Just for completeness, I ran into a similar issue, but to fix it I had to mock out calls to matplotlib.pyplot.figure
instead. I realize this isn't exactly what was asked, but this took me a while to figure out after coming across this thread, so I wanted to post it here.
If, for instance, your plot_graph.py
looked like this:
import matplotlib.pyplot as plt
def func_plot():
fig = plt.figure()
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()
then, at least in my case (running unit tests on a terminal that has no X11 forwarding and errors out when it tries to open a plot), I needed the following in test_plot_graph.py
to run my test:
from plot_graph import func_plot
from unittest.mock import patch
# unittest boilerplate...
@patch('matplotlib.pyplot.figure')
def test_func_plot(self, mock_fig):
# whatever tests I want...
mock_fig.assert_called() # some assertion on the mock object

- 12,340
- 5
- 53
- 75