<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>svnscha - testing</title>
    <subtitle>automating annoying tasks, sharing tips, and embracing less frustration</subtitle>
    <link rel="self" type="application/atom+xml" href="https://svnscha.de/tags/testing/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://svnscha.de"/>
    <generator uri="https://astro.build/">Astro</generator>
    <updated>2025-03-25T00:00:00+00:00</updated>
    <id>https://svnscha.de/tags/testing/atom.xml</id>
    <entry xml:lang="en">
        <title>C++: How to measure code coverage with lcov and GTest</title>
        <published>2025-03-25T00:00:00+00:00</published>
        <updated>2025-03-25T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/cpp-code-coverage/"/>
        <id>https://svnscha.de/posts/cpp-code-coverage/</id>
        <summary type="html">Because you want to know which parts of your C++ code are actually being tested.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/cpp-code-coverage/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;Because you want to know which parts of your C++ code are actually being tested – not just assumed to be. Code coverage isn't about perfection, but about confidence. And with the right setup, you can easily visualize what's being tested and what's quietly collecting dust.&lt;/p&gt;
&lt;p&gt;In this guide, we'll walk through:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setting up &lt;code&gt;lcov&lt;/code&gt; and GTest&lt;/li&gt;
&lt;li&gt;Writing effective coverage-focused tests&lt;/li&gt;
&lt;li&gt;Running the tests and generating reports&lt;/li&gt;
&lt;li&gt;Interpreting results and achieving real insight&lt;/li&gt;
&lt;li&gt;Automating it all via GitHub Actions&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-try-it-yourself&quot;&gt;📦 Try It Yourself&lt;/h3&gt;
&lt;p&gt;Check out the working example repository here:&lt;/p&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://github.com/svnscha/cpp-coverage-example&quot;&gt;github.com/svnscha/cpp-coverage-example&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A minimal &lt;code&gt;MyQueue&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;Unit tests using GTest&lt;/li&gt;
&lt;li&gt;Full &lt;code&gt;lcov&lt;/code&gt; and &lt;code&gt;genhtml&lt;/code&gt; integration&lt;/li&gt;
&lt;li&gt;A GitHub Actions workflow for automated code coverage with a threshold&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;1-install-required-tools&quot;&gt;1. Install Required Tools&lt;/h3&gt;
&lt;p&gt;Make sure your environment has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lcov&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A C++ compiler (GCC or Clang)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cmake&lt;/code&gt;, &lt;code&gt;ninja&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;GTest (or install &lt;code&gt;libgtest-dev&lt;/code&gt; on Ubuntu)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-build-with-coverage-instrumentation&quot;&gt;2. Build with Coverage Instrumentation&lt;/h3&gt;
&lt;p&gt;To generate coverage data, compile your code with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--coverage&lt;/code&gt;: Coverage instrumentation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-g&lt;/code&gt;: Debug information&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-O0&lt;/code&gt;: No optimization (to avoid inlining, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-minimal-cmake-snippet&quot;&gt;🛠 Minimal CMake Snippet&lt;/h4&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cmake&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;option&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(ENABLE_COVERAGE &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Enable code coverage reporting&quot;&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; OFF&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(enable_coverage &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(ENABLE_COVERAGE &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;AND&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; CMAKE_CXX_COMPILER_ID &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;MATCHES&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;GNU|Clang&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        target_compile_options&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;${target}&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; PRIVATE --coverage -O0 -g)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;        target_link_options(&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;${target}&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; PRIVATE --coverage)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;    endif&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;endfunction&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;enable_testing&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;add_library&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(MyLibrary ...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;add_executable&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(MyTests ...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(MyTests PRIVATE MyLibrary GTest::gtest_main)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;include&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(GTest)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;gtest_discover_tests(MyTests)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;enable_coverage(MyLibrary)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;enable_coverage(MyTests)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3-write-tests-that-actually-trigger-all-code-paths&quot;&gt;3. Write Tests That Actually Trigger All Code Paths&lt;/h3&gt;
&lt;p&gt;Here’s a small utility class as an example:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#4EC9B0&quot;&gt; MyQueue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;public:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt; Push&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; val&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;        _q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;val&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;    void&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt; Pop&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;() &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C586C0&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;_q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C586C0&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;        _q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;pop&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;    bool&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt; IsEmpty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#C586C0&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; _q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(); }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;private:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4EC9B0&quot;&gt;    std&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#4EC9B0&quot;&gt;queue&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;_q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now test both normal and edge cases:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;TEST&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;MyQueueTest&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;PopWhenEmpty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4EC9B0&quot;&gt;    MyQueue&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;    q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Pop&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;();&lt;/span&gt;&lt;span style=&quot;color:#6A9955&quot;&gt; // Hit the early return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    EXPECT_TRUE&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;IsEmpty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;TEST&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;MyQueueTest&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;PushAndPop&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#4EC9B0&quot;&gt;    MyQueue&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;    q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Push&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    EXPECT_FALSE&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;IsEmpty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;    q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Pop&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    EXPECT_TRUE&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;q&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;IsEmpty&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;4-run-tests-and-generate-coverage-report&quot;&gt;4. Run Tests and Generate Coverage Report&lt;/h3&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;cmake&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; build&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;DENABLE_COVERAGE&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;ON&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;Debug&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;cmake&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;ctest&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;failure&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then generate the coverage report:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;lcov&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;directory&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; . --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;capture&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; coverage&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;rc&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; geninfo_auto_base&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;ignore&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;errors&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; mismatch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;lcov&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;remove&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; coverage&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '/usr/*'&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '*/tests/*'&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; coverage&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;filtered&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;info&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;genhtml&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; coverage&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;filtered&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;directory&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; coverage&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;report&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Open this in your browser:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;build/coverage-report/index.html&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;video class=&quot;cast&quot; src=&quot;/casts/cpp-coverage-example.webm&quot; controls&gt;
  Your browser does not support the video tag.
&lt;/video&gt;
&lt;h3 id=&quot;5-automation&quot;&gt;5. Automation&lt;/h3&gt;
&lt;p&gt;Now, having the coverage report in place is a great start. But it's not enough to just have the coverage report. You need to automate it so that every time you run your tests, you get a detailed report of what was covered and what wasn't.&lt;/p&gt;
&lt;p&gt;To get started, you can setup a GitHub workflow with threshold tests, upload the reports or do post-processing on the report.&lt;/p&gt;
&lt;p&gt;Either way, the key is to have a way to run tests and generate reports. Here's an example workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/svnscha/cpp-coverage-example/blob/main/.github/workflows/coverage.yml&quot;&gt;.github/workflows/coverage.yml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/svnscha/cpp-coverage-example/pull/1&quot;&gt;Example Pull Request failing because of missing coverage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/svnscha/cpp-coverage-example/pull/2&quot;&gt;Example Pull Request passing coverage tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;What You Did&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Install&lt;/td&gt;
&lt;td&gt;Set up &lt;code&gt;lcov&lt;/code&gt;, gtest, gcc, and cmake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Build&lt;/td&gt;
&lt;td&gt;Compiled with --coverage and no optimizations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Test&lt;/td&gt;
&lt;td&gt;Hit both happy paths and edge cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Report&lt;/td&gt;
&lt;td&gt;Generated detailed HTML coverage report&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Code coverage doesn't guarantee perfect tests, but it gives you visibility. When paired with thoughtful test cases (especially edge cases), it helps ensure your code behaves correctly - even when things go sideways.&lt;/p&gt;
&lt;p&gt;Even small utility classes deserve this level of care.&lt;/p&gt;
&lt;p&gt;And with &lt;code&gt;lcov&lt;/code&gt;, you can turn &quot;I think I tested this&quot; into &quot;Yes, this line has been executed 12 times during CI.&quot;&lt;/p&gt;
</content>
    </entry>
</feed>
