Xvfb makes fake X11 for CI

Continuous integration for program that plot or need a display can be tricky, since in many cases the CI doesn’t have an X11 display server. Workarounds include:

  • Pytest conditional tests that detect CI via environment variable, totally avoiding generating plots. This can reduce code coverage.
  • generate plots using xvfb dummy X11 display server. This maintains code coverage, and may allow dumping plots to disk for further checks


This method uses X server virtual framebuffer (Xvfb) on continuous integration services.

GitHub Actions

Add to the “.github/workflows/ci.yml”, and assuming the project uses PyTest, the xvfb-action enables Xvfb for that command:

- name: Run headless test
  uses: GabrielBB/xvfb-action@v1.2
    run: pytest


Travis-CI supports Xvfb by adding to project “.travis.yml”:

services: xvfb

Detect CI inside Python

Pytest handles conditional tests well.

import os
import pytest

CI = os.environ.get('CI') in ('True', 'true')

@pytest.mark.skipif(CI, reason="no plots for CI")
def test_myfun():
    from matplotlib.pyplot import figure,show


CI Environment variables

These CI’s and more set the environment variable CI as a de facto standard for easy CI detection.