In this blog post we’ll give an example of how these new features work, and outline some of the use cases and workflow for collecting coverage profiles from integration tests.In this blog post we’ll give an example of how these new features work, and outline some of the use cases and workflow for collecting coverage profiles from integration tests.

A Beginner's Guide to Code Coverage for Go Integration Tests

Code coverage tools help developers determine what fraction of a source code base is executed (covered) when a given test suite is executed.

\ Go has for some time provided support (introduced in the Go 1.2 release) to measure code coverage at the package level, using the "-cover" flag of the “go test” command.

\ This tooling works well in most cases, but has some weaknesses for larger Go applications. For such applications, developers often write “integration” tests that verify the behavior of an entire program (in addition to package-level unit tests).

\ This type of test typically involves building a complete application binary, then running the binary on a set of representative inputs (or under production load, if it is a server) to ensure that all of the component packages are working correctly together, as opposed to testing individual packages in isolation.

\ Because the integration test binaries are built with “go build” and not “go test”, Go’s tooling didn’t provide any easy way to collect a coverage profile for these tests, up until now.

\ With Go 1.20, you can now build coverage-instrumented programs using “go build -cover”, then feed these instrumented binaries into an integration test to extend the scope of coverage testing.

\ In this blog post we’ll give an example of how these new features work, and outline some of the use cases and workflow for collecting coverage profiles from integration tests.

Example

Let’s take a very small example program, write a simple integration test for it, and then collect a coverage profile from the integration test.

\ For this exercise we’ll use the “mdtool” markdown processing tool from gitlab.com/golang-commonmark/mdtool. This is a demo program designed to show how clients can use the package gitlab.com/golang-commonmark/markdown, a markdown-to-HTML conversion library.

Set up for mdtool

First let’s download a copy of “mdtool” itself (we’re picking a specific version just to make these steps reproducible):

$ git clone https://gitlab.com/golang-commonmark/mdtool.git ... $ cd mdtool $ git tag example e210a4502a825ef7205691395804eefce536a02f $ git checkout example ... $ 

A simple integration test

Now we’ll write a simple integration test for “mdtool”; our test will build the “mdtool” binary, then run it on a set of input markdown files. This very simple script runs the “mdtool” binary on each file from a test data directory, checking to make sure that it produces some output and doesn’t crash.

$ cat integration_test.sh #!/bin/sh BUILDARGS="$*" # # Terminate the test if any command below does not complete successfully. # set -e # # Download some test inputs (the 'website' repo contains various *.md files). # if [ ! -d testdata ]; then   git clone https://go.googlesource.com/website testdata   git -C testdata tag example 8bb4a56901ae3b427039d490207a99b48245de2c   git -C testdata checkout example fi # # Build mdtool binary for testing purposes. # rm -f mdtool.exe go build $BUILDARGS -o mdtool.exe . # # Run the tool on a set of input files from 'testdata'. # FILES=$(find testdata -name "*.md" -print) N=$(echo $FILES | wc -w) for F in $FILES do   ./mdtool.exe +x +a $F > /dev/null done echo "finished processing $N files, no crashes" $ 

\ Here is an example run of our test:

$ /bin/sh integration_test.sh ... finished processing 380 files, no crashes $ 

\ Success: we’ve verified that the “mdtool” binary successfully digested a set of input files… but how much of the tool’s source code have we actually exercised? In the next section we’ll collect a coverage profile to find out.

Using the integration test to collect coverage data

Let’s write another wrapper script that invokes the previous script, but builds the tool for coverage and then post-processes the resulting profiles:

$ cat wrap_test_for_coverage.sh #!/bin/sh set -e PKGARGS="$*" # # Setup # rm -rf covdatafiles mkdir covdatafiles # # Pass in "-cover" to the script to build for coverage, then # run with GOCOVERDIR set. # GOCOVERDIR=covdatafiles \   /bin/sh integration_test.sh -cover $PKGARGS # # Post-process the resulting profiles. # go tool covdata percent -i=covdatafiles $ 

Some key things to note about the wrapper above:

  • it passes in the “-cover” flag when running integration_test.sh, which gives us a coverage-instrumented “mdtool.exe” binary
  • it sets the GOCOVERDIR environment variable to a directory into which coverage data files will be written
  • when the test is complete, it runs “go tool covdata percent” to produce a report on percentage of statements covered

\ Here’s the output when we run this new wrapper script:

$ /bin/sh wrap_test_for_coverage.sh ...     gitlab.com/golang-commonmark/mdtool coverage: 48.1% of statements $ # Note: covdatafiles now contains 381 files. 

Voila! We now have some idea of how well our integration tests work in exercising the “mdtool” application’s source code.

\ If we make changes to enhance the test harness, then do a second coverage collection run, we’ll see the changes reflected in the coverage report. For example, suppose we improve our test by adding these two additional lines to integration_test.sh:

./mdtool.exe +ty testdata/README.md  > /dev/null ./mdtool.exe +ta < testdata/README.md  > /dev/null 

\ Running the coverage testing wrapper again:

$ /bin/sh wrap_test_for_coverage.sh finished processing 380 files, no crashes     gitlab.com/golang-commonmark/mdtool coverage: 54.6% of statements $ 

We can see the effects of our change: statement coverage has increased from 48% to 54%.

Selecting packages to cover

By default, “go build -cover” will instrument just the packages that are part of the Go module being built, which in this case is the gitlab.com/golang-commonmark/mdtool package. In some cases however it is useful to extend coverage instrumentation to other packages; this can be accomplished by passing “-coverpkg” to “go build -cover”.

\ For our example program, “mdtool” is in fact largely just a wrapper around the package gitlab.com/golang-commonmark/markdown, so it is interesting to include markdown in the set of packages that are instrumented.

\ Here’s the go.mod file for “mdtool”:

$ head go.mod module gitlab.com/golang-commonmark/mdtool  go 1.17  require (     github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8     gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a ) 

\ We can use the “-coverpkg” flag to control which packages are selected for inclusion in the coverage analysis to include one of the deps above. Here’s an example:

$ /bin/sh wrap_test_for_coverage.sh -coverpkg=gitlab.com/golang-commonmark/markdown,gitlab.com/golang-commonmark/mdtool ...     gitlab.com/golang-commonmark/markdown   coverage: 70.6% of statements     gitlab.com/golang-commonmark/mdtool coverage: 54.6% of statements $ 

Working with coverage data files

When a coverage integration test has completed and written out a set of raw data files (in our case, the contents of the covdatafiles directory), we can post-process these files in various ways.

Converting profiles to ‘-coverprofile’ text format

When working with unit tests, you can run go test -coverprofile=abc.txt to write a text-format coverage profile for a given coverage test run.

\ With binaries built with go build -cover, you can generate a text-format profile after the fact by running go tool covdata textfmt on the files emitted into the GOCOVERDIR directory.

\ Once this step is complete, you can use go tool cover -func=<file> or go tool cover -html=<file> to interpret/visualize the data just as you would with go test -coverprofile.

\ Example:

$ /bin/sh wrap_test_for_coverage.sh ... $ go tool covdata textfmt -i=covdatafiles -o=cov.txt $ go tool cover -func=cov.txt gitlab.com/golang-commonmark/mdtool/main.go:40:     readFromStdin   100.0% gitlab.com/golang-commonmark/mdtool/main.go:44:     readFromFile    80.0% gitlab.com/golang-commonmark/mdtool/main.go:54:     readFromWeb 0.0% gitlab.com/golang-commonmark/mdtool/main.go:64:     readInput   80.0% gitlab.com/golang-commonmark/mdtool/main.go:74:     extractText 100.0% gitlab.com/golang-commonmark/mdtool/main.go:88:     writePreamble   100.0% gitlab.com/golang-commonmark/mdtool/main.go:111:    writePostamble  100.0% gitlab.com/golang-commonmark/mdtool/main.go:118:    handler     0.0% gitlab.com/golang-commonmark/mdtool/main.go:139:    main        51.6% total:                          (statements)    54.6% $ 

Merging raw profiles with ‘go tool covdata merge’

Each execution of a “-cover” built application will write out one or more data files to the directory specified in the GOCOVERDIR environment variable. If an integration test performs N program executions, you’ll wind up with O(N) files in your output directory.

\ There is typically a lot of duplicated content in the data files, so to compact the data and/or combine data sets from different integration test runs, you can use the go tool covdata merge command to merge profiles together. Example:

$ /bin/sh wrap_test_for_coverage.sh finished processing 380 files, no crashes     gitlab.com/golang-commonmark/mdtool coverage: 54.6% of statements $ ls covdatafiles covcounters.13326b42c2a107249da22f6e0d35b638.772307.1677775306041466651 covcounters.13326b42c2a107249da22f6e0d35b638.772314.1677775306053066987 ... covcounters.13326b42c2a107249da22f6e0d35b638.774973.1677775310032569308 covmeta.13326b42c2a107249da22f6e0d35b638 $ ls covdatafiles | wc     381     381   27401 $ rm -rf merged ; mkdir merged ; go tool covdata merge -i=covdatafiles -o=merged $ ls merged covcounters.13326b42c2a107249da22f6e0d35b638.0.1677775331350024014 covmeta.13326b42c2a107249da22f6e0d35b638 $ 

The go tool covdata merge operation also accepts a -pkg flag that can be used to select out a specific package or set of packages, if that is desired.

\ This merge capability is also useful to combine results from different types of test runs, including runs generated by other test harnesses.

Wrap-up

That covers it: with the 1.20 release, Go’s coverage tooling is no longer limited to package tests, but supports collecting profiles from larger integration tests. We hope you will make good use of the new features to help understand how well your larger and more complicated tests are working, and which parts of your source code they are exercising.

\ Please try out these new features, and as always if you encounter problems, file issues on our GitHub issue tracker. Thanks.


By Than McIntosh

\ Photo by Annie Spratt on Unsplash

\ This article is available on The Go Blog under a CC BY 4.0 DEED license.

Market Opportunity
LightLink Logo
LightLink Price(LL)
$0.004372
$0.004372$0.004372
-2.97%
USD
LightLink (LL) Live Price Chart
Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact [email protected] for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Ethereum ETFs Lead on Jan 15 as Bitcoin Wins the Week

Ethereum ETFs Lead on Jan 15 as Bitcoin Wins the Week

The post Ethereum ETFs Lead on Jan 15 as Bitcoin Wins the Week appeared on BitcoinEthereumNews.com. Key Highlights: Ethereum ETFs led the daily inflows on January
Share
BitcoinEthereumNews2026/01/16 15:18
SEC chair backs rule to let companies ditch quarterly earnings reports

SEC chair backs rule to let companies ditch quarterly earnings reports

SEC Chairman Atkins said on Friday that his agency plans to push forward a rule change to give companies the option to ditch quarterly earnings reports. He confirmed this live on CNBC’s Squawk Box, saying, “I welcome that posting by the president, and I have talked to him about it.” This move follows Donald Trump’s […]
Share
Cryptopolitan2025/09/19 22:42
Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025

Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025

BitcoinWorld Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025 Are you ready to witness a phenomenon? The world of technology is abuzz with the incredible rise of Lovable AI, a startup that’s not just breaking records but rewriting the rulebook for rapid growth. Imagine creating powerful apps and websites just by speaking to an AI – that’s the magic Lovable brings to the masses. This groundbreaking approach has propelled the company into the spotlight, making it one of the fastest-growing software firms in history. And now, the visionary behind this sensation, co-founder and CEO Anton Osika, is set to share his invaluable insights on the Disrupt Stage at the highly anticipated Bitcoin World Disrupt 2025. If you’re a founder, investor, or tech enthusiast eager to understand the future of innovation, this is an event you cannot afford to miss. Lovable AI’s Meteoric Ascent: Redefining Software Creation In an era where digital transformation is paramount, Lovable AI has emerged as a true game-changer. Its core premise is deceptively simple yet profoundly impactful: democratize software creation. By enabling anyone to build applications and websites through intuitive AI conversations, Lovable is empowering the vast majority of individuals who lack coding skills to transform their ideas into tangible digital products. This mission has resonated globally, leading to unprecedented momentum. The numbers speak for themselves: Achieved an astonishing $100 million Annual Recurring Revenue (ARR) in less than a year. Successfully raised a $200 million Series A funding round, valuing the company at $1.8 billion, led by industry giant Accel. Is currently fielding unsolicited investor offers, pushing its valuation towards an incredible $4 billion. As industry reports suggest, investors are unequivocally “loving Lovable,” and it’s clear why. This isn’t just about impressive financial metrics; it’s about a company that has tapped into a fundamental need, offering a solution that is both innovative and accessible. The rapid scaling of Lovable AI provides a compelling case study for any entrepreneur aiming for similar exponential growth. The Visionary Behind the Hype: Anton Osika’s Journey to Innovation Every groundbreaking company has a driving force, and for Lovable, that force is co-founder and CEO Anton Osika. His journey is as fascinating as his company’s success. A physicist by training, Osika previously contributed to the cutting-edge research at CERN, the European Organization for Nuclear Research. This deep technical background, combined with his entrepreneurial spirit, has been instrumental in Lovable’s rapid ascent. Before Lovable, he honed his skills as a co-founder of Depict.ai and a Founding Engineer at Sana. Based in Stockholm, Osika has masterfully steered Lovable from a nascent idea to a global phenomenon in record time. His leadership embodies a unique blend of profound technical understanding and a keen, consumer-first vision. At Bitcoin World Disrupt 2025, attendees will have the rare opportunity to hear directly from Osika about what it truly takes to build a brand that not only scales at an incredible pace in a fiercely competitive market but also adeptly manages the intense cultural conversations that inevitably accompany such swift and significant success. His insights will be crucial for anyone looking to understand the dynamics of high-growth tech leadership. Unpacking Consumer Tech Innovation at Bitcoin World Disrupt 2025 The 20th anniversary of Bitcoin World is set to be marked by a truly special event: Bitcoin World Disrupt 2025. From October 27–29, Moscone West in San Francisco will transform into the epicenter of innovation, gathering over 10,000 founders, investors, and tech leaders. It’s the ideal platform to explore the future of consumer tech innovation, and Anton Osika’s presence on the Disrupt Stage is a highlight. His session will delve into how Lovable is not just participating in but actively shaping the next wave of consumer-facing technologies. Why is this session particularly relevant for those interested in the future of consumer experiences? Osika’s discussion will go beyond the superficial, offering a deep dive into the strategies that have allowed Lovable to carve out a unique category in a market long thought to be saturated. Attendees will gain a front-row seat to understanding how to identify unmet consumer needs, leverage advanced AI to meet those needs, and build a product that captivates users globally. The event itself promises a rich tapestry of ideas and networking opportunities: For Founders: Sharpen your pitch and connect with potential investors. For Investors: Discover the next breakout startup poised for massive growth. For Innovators: Claim your spot at the forefront of technological advancements. The insights shared regarding consumer tech innovation at this event will be invaluable for anyone looking to navigate the complexities and capitalize on the opportunities within this dynamic sector. Mastering Startup Growth Strategies: A Blueprint for the Future Lovable’s journey isn’t just another startup success story; it’s a meticulously crafted blueprint for effective startup growth strategies in the modern era. Anton Osika’s experience offers a rare glimpse into the practicalities of scaling a business at breakneck speed while maintaining product integrity and managing external pressures. For entrepreneurs and aspiring tech leaders, his talk will serve as a masterclass in several critical areas: Strategy Focus Key Takeaways from Lovable’s Journey Rapid Scaling How to build infrastructure and teams that support exponential user and revenue growth without compromising quality. Product-Market Fit Identifying a significant, underserved market (the 99% who can’t code) and developing a truly innovative solution (AI-powered app creation). Investor Relations Balancing intense investor interest and pressure with a steadfast focus on product development and long-term vision. Category Creation Carving out an entirely new niche by democratizing complex technologies, rather than competing in existing crowded markets. Understanding these startup growth strategies is essential for anyone aiming to build a resilient and impactful consumer experience. Osika’s session will provide actionable insights into how to replicate elements of Lovable’s success, offering guidance on navigating challenges from product development to market penetration and investor management. Conclusion: Seize the Future of Tech The story of Lovable, under the astute leadership of Anton Osika, is a testament to the power of innovative ideas meeting flawless execution. Their remarkable journey from concept to a multi-billion-dollar valuation in record time is a compelling narrative for anyone interested in the future of technology. By democratizing software creation through Lovable AI, they are not just building a company; they are fostering a new generation of creators. His appearance at Bitcoin World Disrupt 2025 is an unmissable opportunity to gain direct insights from a leader who is truly shaping the landscape of consumer tech innovation. Don’t miss this chance to learn about cutting-edge startup growth strategies and secure your front-row seat to the future. Register now and save up to $668 before Regular Bird rates end on September 26. To learn more about the latest AI market trends, explore our article on key developments shaping AI features. This post Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025 first appeared on BitcoinWorld.
Share
Coinstats2025/09/17 23:40