CINXE.COM

Lua - Codecov

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> <head profile="http://gmpg.org/xfn/11"> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="google-site-verification" content="vJJzG_HitBMzWgMMYHRCAa6Y2voMwC9OTHuxgHL2358" /> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" /> <title>Lua - Codecov</title> <!-- WP HEAD --> <meta name='robots' content='index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1' /> <style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style> <!-- This site is optimized with the Yoast SEO plugin v23.6 - https://yoast.com/wordpress/plugins/seo/ --> <link rel="canonical" href="https://about.codecov.io/language/lua/" /> <meta property="og:locale" content="en_US" /> <meta property="og:type" content="article" /> <meta property="og:title" content="Lua - Codecov" /> <meta property="og:url" content="https://about.codecov.io/language/lua/" /> <meta property="og:site_name" content="Codecov" /> <meta property="article:publisher" content="https://www.facebook.com/Codecov-106795907636673/" /> <meta property="article:modified_time" content="2022-01-11T16:40:04+00:00" /> <meta property="og:image" content="https://about.codecov.io/wp-content/uploads/2022/04/0433_SocialCard_LinkedIn-100-1.jpg" /> <meta property="og:image:width" content="1200" /> <meta property="og:image:height" content="637" /> <meta property="og:image:type" content="image/jpeg" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:site" content="@codecov" /> <script type="application/ld+json" class="yoast-schema-graph">{"@context":"https://schema.org","@graph":[{"@type":"WebPage","@id":"https://about.codecov.io/language/lua/","url":"https://about.codecov.io/language/lua/","name":"Lua - Codecov","isPartOf":{"@id":"https://about.codecov.io/#website"},"datePublished":"2020-08-12T23:45:59+00:00","dateModified":"2022-01-11T16:40:04+00:00","breadcrumb":{"@id":"https://about.codecov.io/language/lua/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https://about.codecov.io/language/lua/"]}]},{"@type":"BreadcrumbList","@id":"https://about.codecov.io/language/lua/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://about.codecov.io/"},{"@type":"ListItem","position":2,"name":"Lua"}]},{"@type":"WebSite","@id":"https://about.codecov.io/#website","url":"https://about.codecov.io/","name":"Codecov","description":"Code coverage done right.","publisher":{"@id":"https://about.codecov.io/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://about.codecov.io/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https://about.codecov.io/#organization","name":"Codecov","url":"https://about.codecov.io/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https://about.codecov.io/#/schema/logo/image/","url":"https://about.codecov.io/wp-content/uploads/2020/09/codecov.svg","contentUrl":"https://about.codecov.io/wp-content/uploads/2020/09/codecov.svg","width":1,"height":1,"caption":"Codecov"},"image":{"@id":"https://about.codecov.io/#/schema/logo/image/"},"sameAs":["https://www.facebook.com/Codecov-106795907636673/","https://x.com/codecov","https://www.instagram.com/codecov/","https://www.linkedin.com/company/codecov/","https://www.youtube.com/channel/UCj-fJuvXv-m05HkSNn0OS9g/featured"]}]}</script> <!-- / Yoast SEO plugin. --> <link rel='stylesheet' id='wp-block-library-css' href='https://about.codecov.io/wp-includes/css/dist/block-library/style.min.css?ver=6.7.2' type='text/css' media='all' /> <style id='classic-theme-styles-inline-css' type='text/css'> /*! This file is auto-generated */ .wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none} </style> <style id='global-styles-inline-css' type='text/css'> :root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;} :where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;} :where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;} :root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;} </style> <link rel='stylesheet' id='likebtn_style-css' href='https://about.codecov.io/wp-content/plugins/likebtn-like-button/public/css/style.css?ver=6.7.2' type='text/css' media='all' /> <link rel='stylesheet' id='wp-pagenavi-css' href='https://about.codecov.io/wp-content/plugins/wp-pagenavi/pagenavi-css.css?ver=2.70' type='text/css' media='all' /> <link rel='stylesheet' id='styles-css' href='https://about.codecov.io/wp-content/themes/codecov/style.css?ver=1742396675' type='text/css' media='all' /> <script type="text/javascript" id="likebtn_frontend-js-extra"> /* <![CDATA[ */ var likebtn_eh_data = {"ajaxurl":"https:\/\/about.codecov.io\/wp-admin\/admin-ajax.php","security":"d7bf4ba2ea"}; /* ]]> */ </script> <script type="text/javascript" src="https://about.codecov.io/wp-content/plugins/likebtn-like-button/public/js/frontend.js?ver=6.7.2" id="likebtn_frontend-js"></script> <script type="text/javascript" defer data-domain='about.codecov.io' data-api='https://about.codecov.io/wp-json/fb8d43/v1/fef8/87d0ca76' data-cfasync='false' src="//about.codecov.io/wp-content/uploads/0ef4f2a49f/92e3cfb7.js?ver=1719335001" id="plausible"></script> <script type="text/javascript" id="plausible-analytics-js-after"> /* <![CDATA[ */ window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) } /* ]]> */ </script> <script type="text/javascript" src="https://about.codecov.io/wp-content/plugins/jquery-updater/js/jquery-3.7.1.min.js?ver=3.7.1" id="jquery-core-js"></script> <script type="text/javascript" src="https://about.codecov.io/wp-content/plugins/jquery-updater/js/jquery-migrate-3.5.2.min.js?ver=3.5.2" id="jquery-migrate-js"></script> <link rel="https://api.w.org/" href="https://about.codecov.io/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://about.codecov.io/wp-json/wp/v2/language/153" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://about.codecov.io/xmlrpc.php?rsd" /> <link rel='shortlink' href='https://about.codecov.io/?p=153' /> <link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://about.codecov.io/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fabout.codecov.io%2Flanguage%2Flua%2F" /> <link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://about.codecov.io/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fabout.codecov.io%2Flanguage%2Flua%2F&#038;format=xml" /> <meta name='plausible-analytics-version' content='2.1.4' /> <!-- FAVICON INFO --> <link rel="apple-touch-icon" sizes="57x57" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="60x60" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="72x72" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="76x76" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="114x114" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="120x120" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="144x144" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="152x152" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-152x152.png"> <link rel="apple-touch-icon" sizes="180x180" href="/wp-content/themes/codecov/assets/brand/icons/favicons/apple-icon-180x180.png"> <link rel="icon" type="image/png" sizes="192x192" href="/wp-content/themes/codecov/assets/brand/icons/favicons/android-icon-192x192.png"> <link rel="icon" type="image/png" sizes="32x32" href="/wp-content/themes/codecov/assets/brand/icons/favicons/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="96x96" href="/wp-content/themes/codecov/assets/brand/icons/favicons/favicon-96x96.png"> <link rel="icon" type="image/png" sizes="16x16" href="/wp-content/themes/codecov/assets/brand/icons/favicons/favicon-16x16.png"> <!-- <link rel="manifest" href="/wp-content/themes/codecov/assets/brand/icons/favicons/manifest.json">--> <meta name="msapplication-TileColor" content="#ff0077"> <meta name="msapplication-TileImage" content="/wp-content/themes/codecov/assets/brand/icons/favicons/ms-icon-144x144.png"> <meta name="theme-color" content="#ff0077"> <!-- Facebook Verification --> <meta name="facebook-domain-verification" content="d8454acosfhz6aizm750a0qtfm99pn" /> <!-- COMMENT SCRIPTS --> <!-- Google Tag Manager --> <script> (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-KGH2DSG'); window.dataLayer.push({ "codecov": { "page": { "type": "Language" } } }); </script> <!-- End Google Tag Manager --> </head> <body class="language-template-default single single-language postid-153 fl-builder-2-8-4-1"> <!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-KGH2DSG" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <!-- End Google Tag Manager (noscript) --><div id="mega-header"><div class="hero-texture"><div class="texture-left"></div><div class="texture-right"></div></div><header id="header"> <div class="container"> <div class="row"> <div class="col-12"> <div class="header__content"> <!-- LOGO --> <a class="header__logo" href="https://about.codecov.io"> <img src="/wp-content/themes/codecov/assets/brand/sentry-cobranding/logos/codecov-by-sentry-logo.svg" title="Code Coverage by Codecov" alt="Code Coverage by Codecov" /> </a> <!-- MAIN NAVIGATION --> <nav class="header__main-navigation"> <ul> <li> <a href="/product/features/">Product</a> <!-- PRODUCT MENU --> <div class="menu menu--product"> <div class="row"> <div class="col-md-12"> <ul> <li><a href="/product/features/">Features</a></li> <li><a href="/product/integrations/">Integrations</a></li> <li><a href="/product/documentation/">Docs</a></li> <li><a href="/product/api/">API</a></li> <li><a href="/product/status/">Status</a></li> </ul> </div> </div> <!--<div class="row callout"> <div class="col"> <p><a href="https://about.codecov.io/blog/introducing-codecovs-new-uploader/"><span class="badge badge-primary">Product Update</span>Introducing Codecov's New Uploader<i class="fa fa-arrow-right"></i></a></p> </div> </div>--> </div> </li> <li> <a href="/product/documentation/" target="_BLANK">Docs</a> </li> <li> <a href="/customers/">Customers</a> </li> <li> <a href="/resources/">Blog</a> </li> <li><a href="/pricing/">Pricing</a></li> <li> <a href="/contact/">Help</a> <!-- COMPANY --> <div class="menu menu--company"> <div class="row"> <div class="col-md-12"> <ul> <li><a href="https://codecovpro.zendesk.com/">Pro Support</a></li> <li><a href="https://codecoventerprise.zendesk.com/">Enterprise Support</a></li> <li><a href="https://community.codecov.com/">Community</a></li> <li><a href="/contact/">Contact Us</a></li> </ul> </div> </div> <!--<div class="row callout"> <div class="col"> <p><a href="https://angel.co/job-collections/52-best-startup-companies-to-watch-out-for-in-2020" target="_blank" rel="noopener noreferrer"><span class="badge badge-primary">Angel List</span>Company to watch out for in 2020 <i class="fa fa-arrow-right"></i></a></p> </div> </div>--> </div> </li> </ul> </nav> <!-- LOGIN NAVIGATION --> <nav class="header__login-navigation"> <ul> <li class="d-inline-inline-block d-lg-none"> <div class="effect-02"> <div class="menu-icon js-menu_toggle"> <span class="menu-icon_box"> <span class="menu-icon_line menu-icon_line--1"></span> <span class="menu-icon_line menu-icon_line--2"></span> <span class="menu-icon_line menu-icon_line--3"></span> </span> </div> </div> </li> <li class="d-none d-lg-inline-block"> <a class="header--login" href="javascript:;">Login</a> <div class="menu menu--login"> <div class="row"> <div class="col"> <ul> <li><a href="https://codecov.io/login/gh"><img src="/wp-content/themes/codecov/assets/logos/ci/github/github-icon.svg" /> GitHub</a></li> <li><a href="https://codecov.io/login/gl"><img src="/wp-content/themes/codecov/assets/logos/ci/gitlab/gitlab-icon.svg" /> GitLab</a></li> <li><a href="https://codecov.io/login/bb"><img src="/wp-content/themes/codecov/assets/logos/ci/bitbucket/bitbucket-icon.svg" /> Bitbucket</a></li> <li><a href="https://api.codecov.io/login/sentry?to=https%3A%2F%2Fapp.codecov.io%2Fsentry"><img src="/wp-content/themes/codecov/assets/logos/sentry-logo.svg" /> Sentry</a></li> </ul> </div> </div> </div> </li> <li class="d-none d-lg-inline-block"> <!-- <a href="/sign-up/" class="btn btn-md btn-dark-blue btn-signup">Sign Up</a>--> <a href="/demo/" class="btn btn-md btn-dark-blue btn-signup plausible-event-name=Nav+Click+CTA">Get Demo</a> </li> </ul> </nav> <!-- MOBILE NAVIGATION --> <nav class="header__mobile-navigation"> <ul> <li> <a href="/product/" class="has-menu">Product</a> <!-- PRODUCT MENU --> <div class="menu menu--product"> <div class="row"> <div class="col"> <ul> <li><a href="/product/">Overview</a></li> <li><a href="/product/features/">Features</a></li> <li><a href="/product/integrations/">Integrations</a></li> <li><a href="/product/getting-started/" class="d-none">Getting Started</a></li> <li><a href="/product/documentation/">Documentation</a></li> <li><a href="/product/api/">API</a></li> <li><a href="/product/status/">Status</a></li> </ul> </div> </div> </div> </li> <li> <a href="/customers/">Customers</a> </li> <li> <a href="/resources/">Blog</a> </li> <li><a href="https://docs.codecov.io" target="_blank" rel="noopener noreferrer">Docs</a></li> <li><a href="/pricing/">Pricing</a></li> <li><a href="/contact/">Contact</a></li> <li><a href="/sign-up/">Login</a></li> </ul> </nav> </div> </div> </div> </div> </header><section id="hero"><div class="container"> <div class="row d-flex justify-content-start flex-column align-items-center"> <img src="https://about.codecov.io/wp-content/uploads/2020/08/lua-logo.svg" class="mb-3" /> </div></div></section></div><section id="scrollbar"> <div class="container"> <div class="row d-flex justify-content-between align-items-center"> <!-- LOGO --> <a class="logo" href="https://about.codecov.io"> <img src="/wp-content/themes/codecov/assets/brand/sentry-cobranding/logos/codecov-by-sentry-logo.svg" title="Codecov" alt="Codecov" /> </a> <a class="d-flex d-lg-none btn btn-md btn-primary" href="https://codecov.io/login/">Get Started For Free</a> <ul class="list-inline d-none d-lg-block"> <!--<li class="mr-2"> <h6 class="my-0">Get Started With</h6> </li> <li> <a class="btn btn-sm btn-white btn-github plausible-event-name=Scrollbar+Click+Github" href="https://codecov.io/login/gh"><img src="/wp-content/themes/codecov/assets/logos/ci/github/github-icon.svg"> GitHub</a> </li> <li> <a class="btn btn-sm btn-white btn-gitlab plausible-event-name=Scrollbar+Click+Gitlab" href="https://codecov.io/login/gl"><img src="/wp-content/themes/codecov/assets/logos/ci/gitlab/gitlab-icon.svg"> GitLab</a> </li> <li> <a class="btn btn-sm btn-white btn-bitbucket plausible-event-name=Scrollbar+Click+Bitbucket" href="https://codecov.io/login/bb"><img src="/wp-content/themes/codecov/assets/logos/ci/bitbucket/bitbucket-icon.svg"> Bitbucket</a> </li> <li> <a class="btn btn-sm btn-white btn-sentry plausible-event-name=Scrollbar+Click+Sentry" href="https://api.codecov.io/login/sentry?to=https%3A%2F%2Fapp.codecov.io%2Fsentry"><img src="/wp-content/themes/codecov/assets/logos/sentry-logo.svg" /> Sentry</a> </li> --> <li> <a class="btn btn-sm btn-white plausible-event-name=Scrollbar+Click+Login" href="https://codecov.io/login/">Login</a> </li> <li> <a class="btn btn-sm btn-secondary plausible-event-name=Scrollbar+Click+Signup" href="https://about.codecov.io/codecov-free-trial">Try Codecov for Free</a> </li> </ul> </div> </div> </section> <main id="main"> <div class="container"> <div class="row d-flex justify-content-center"> <div class="col-lg-7"> <h2 class="mb-4">Getting Started With Codecov and Lua</h2> <p>After writing unit tests, integration tests, or other tests with your test suite and generating coverage reports with a coverage tool you can upload your coverage reports to Codecov as part of your CI workflow.</p><p>Use the resources below to get started with Codecov and Lua. If you haven't already sign up for Codecov using the button below.</p> <h2 class="mt-5">Resources</h2> <div class="row"> <div class="col-md-4"><h6>Example Repos</h6><ul class="checklist"><li><a href="https://github.com/codecov/example-lua">Example Lua</a></li></ul></div> <div class="col-md-4"><h6>Related Coverage Tools</h6><div class='yarpp yarpp-related yarpp-related-website yarpp-template-yarpp-template-checklist'> <ul class="checklist"> <li><a href="https://about.codecov.io/tool/luacov/" title="LuaCov" >LuaCov</a><!-- (10.0000)--></li> </ul> </div> </div> </div> </div> <div class="col-lg-4 offset-lg-1"> <section id="cta"> <div class="container"> <div class="row d-flex justify-content-center"> <div class="cta__sign-up"> <div class="row d-flex justify-content-center"> <div class="col-12 text-center"> <h4>Ready to get covered?</h4> <p>Join over a million developers in shipping healthier code today. Sign up with your code host below.</p> </div> </div> <div class="row"> <div class="col-12 py-1"> <a class="btn btn-lg btn-white w-100 btn-github" href="#github-login-interstitial" data-fancybox><img src="/wp-content/themes/codecov/assets/logos/ci/github/github-icon.svg"> GitHub</a> </div> <div class="col-12 py-1"> <a class="btn btn-lg btn-white w-100 btn-gitlab plausible-event-name=Click+Gitlab" href="https://app.codecov.io/login/gl"><img src="/wp-content/themes/codecov/assets/logos/ci/gitlab/gitlab-icon.svg"> GitLab</a> </div> <div class="col-12 py-1"> <a class="btn btn-lg btn-white w-100 btn-bitbucket plausible-event-name=Click+Bitbucket" href="https://app.codecov.io/login/bb"><img src="/wp-content/themes/codecov/assets/logos/ci/bitbucket/bitbucket-icon.svg"> Bitbucket</a> </div> <div class="col-12 py-1"> <a class="btn btn-lg btn-white w-100 btn-sentry plausible-event-name=Click+Sentry" href="https://api.codecov.io/login/sentry?to=https%3A%2F%2Fapp.codecov.io%2Fsentry"><img src="/wp-content/themes/codecov/assets/logos/sentry-logo.svg"> Sentry</a> </div> </div> </div> </div> </div> </section> <!--<div class="row"> <div class="col"> <div class="box"> <h5>Need help getting started?</h5> <p>Sometimes getting started with Codecov can be challenging. If you need help there are resources available.</p> <ul class="help-list"> <li><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fabout.codecov.io%2Flanguage%2Flua%2F&text=%40codecov%20need%20some%20help%20getting%20started%20with%20Lua&hashtags=codecoverage" target="_blank"><i class="fa fa-twitter"></i> Tweet at us</a></li> <li><a href="https://community.codecov.io/search?q=Lua" target="_blank"><i class="fab fa-discourse"></i> Ask the community</a></li> <li><a href="https://codecov.freshdesk.com/support/tickets/new" target="_blank"><i class="fa fa-ticket"></i> Submit a ticket</a></li> </ul> <a href="/demo/" class="btn btn-sm btn-pink w-100"><i class="fa fa-video"></i> Schedule a Demo</a> </div> </div> </div>--> </div> </div> <!--<div class="row d-flex justify-content-center mt-5"> <div class="col col-lg-12"> </div> </div> --> </div> <section class="section section--marketechture-resources"> <div class="container"> <div class="row"> <script> var selectedLanguage = 153; var selectedCI=176; var selectedCodeHost=1971; var pageID =153; var relatedResources = [{"ID":4668,"post_author":"39","post_date":"2022-08-04 11:02:04","post_date_gmt":"2022-08-04 15:02:04","post_content":"Code coverage is a metric used to measure how much of your source code has been covered by your test suite. In other words, it tells you what percentage of your code is executed when you run your tests, and helps you find out which parts are not covered by the test. As a C developer, you can use <a href=\"https:\/\/about.codecov.io\/resource\/what-is-code-coverage\/\">code coverage<\/a> to identify gaps in test cases at an early stage and improve the quality of your tests.\r\n\r\n<a href=\"https:\/\/about.codecov.io\">Codecov<\/a> is a reporting tool that can take the code coverage generated by your build tools and convert it into a meaningful representation with graphs and charts which can help you better understand your code coverage. Codecov also integrates smoothly with your existing CI\/CD systems, like <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a>, and provides coverage reports for every commit and pull request so that you have an understanding of how your tests are performing without any hassle.\r\n\r\nIn this tutorial, you'll learn how to set up code coverage using <a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gcc\/Gcov.html\">Gcov<\/a> and how to integrate Codecov with your GitHub repository using a GitHub Action to generate coverage reports every time you push changes or make a pull request. If you'd like more info you can request a <a href=\"https:\/\/about.codecov.io\/demo\/\">demo<\/a> at any time.\r\n\r\nYou can check out the <a href=\"https:\/\/github.com\/codecov\/example-c\">GitHub repo for this tutorial here<\/a>.\r\n<h2>Building the application<\/h2>\r\nFirst, let's create two files to run a calculator application. The app will have 4 functions to perform basic calculator operations (add, subtract, multiply, and divide). Create a file <code>calculator.h<\/code> with the following code:\r\n<pre class=\"hljs c\"><code>double add(double, double);\r\ndouble subtract(double, double);\r\ndouble multiply(double, double);\r\ndouble divide(double, double);\r\n<\/code><\/pre>\r\nand the file <code>calculator.c<\/code> with the following code:\r\n<pre class=\"hljs c\"><code>#include &lt;stdio.h&gt;\r\n\r\n#include \"calculator.h\"\r\n\r\ndouble add(double x, double y) {\r\n return x + y;\r\n}\r\n\r\ndouble subtract(double x, double y) {\r\n return x - y;\r\n}\r\n\r\ndouble multiply(double x, double y) {\r\n return x * y;\r\n}\r\n\r\ndouble divide(double x, double y) {\r\n if (y == 0) {\r\n printf(\"Cannot divide by 0\");\r\n return 0;\r\n }\r\n return x * 1.0 \/ y;\r\n}<\/code><\/pre>\r\n<h2 id=\"running-tests-locally\">Running Tests Locally<\/h2>\r\nThis tutorial assumes you have <code>gcc<\/code> installed and set up on your computer. The tool <code>gcov<\/code> comes bundled with GCC.\r\n<h3>Writing unit tests<\/h3>\r\nNow, let's create a test file for our calculator. Create a <code>test_calculator.c<\/code> file with the following code:\r\n<pre class=\"hljs c\"><code>#include &lt;assert.h&gt;\r\n\r\n#include \"calculator.h\"\r\n\r\nvoid test_add() {\r\n assert(add(1, 2) == 3.0);\r\n assert(add(1.0, 2.0) == 3.0);\r\n assert(add(0, 2.0) == 2.0);\r\n assert(add(2.0, 0) == 2.0);\r\n assert(add(-4, 2.0) == -2.0);\r\n}\r\n\r\nvoid test_subtract() {\r\n assert(subtract(1, 2) == -1.0);\r\n assert(subtract(2, 1) == 1.0);\r\n assert(subtract(1.0, 2.0) == -1.0);\r\n assert(subtract(0, 2.0) == -2.0);\r\n assert(subtract(2.0, 0) == 2.0);\r\n assert(subtract(-4, 2.0) == -6.0);\r\n}\r\n\r\nvoid test_multiply() {\r\n assert(multiply(1, 2) == 2.0);\r\n assert(multiply(1.0, 2.0) == 2.0);\r\n assert(multiply(0, 2.0) == 0.0);\r\n assert(multiply(2.0, 0) == 0.0);\r\n assert(multiply(-4, 2.0) == -8.0);\r\n}\r\n\r\nvoid test_divide() {\r\n assert(divide(1, 2) == 0.5);\r\n assert(divide(1.0, 2.0) == 0.5);\r\n assert(divide(0, 2.0) == 0);\r\n assert(divide(-4, 2.0) == -2.0);\r\n \/\/ assert(divide(2.0, 0) == 0.0);\r\n}\r\n\r\nint main() {\r\n test_add();\r\n test_subtract();\r\n test_multiply();\r\n test_divide();\r\n}\r\n<\/code><\/pre>\r\nYou'll see that we have a bunch of test cases for each mathematical operation. Also, note that we are commenting out the last <code>assert<\/code> in the <code>test_divide<\/code> function. We'll see why in a minute.\r\n<h3>Compiling and running our code<\/h3>\r\nIn order to run our tests and collect coverage, we will need to compile our code into an object file. In order to enable code coverage, you need to pass the <code>-ftest-coverage<\/code> and <code>-fprofile-arcs<\/code> flag to <code>gcc<\/code>. The flag <code>-O0<\/code> is also needed so that the compiler doesn't optimize away our trivial example.\r\n<pre><code class=\"lang-bash\">gcc -fprofile-arcs -ftest-coverage -O0 -o test_calculator test_calculator.c calculator.c<\/code><\/pre>\r\n&gt;f2.\r\nThis will create an executable called <code>test_calculator<\/code> in the current directory as well as <code>test_calculator.gcno<\/code> and calculator.gcno files. They contain important information about how many times individual lines have been executed. Note that these <code>.gcno<\/code> files will be generated for every object file.\r\n\r\nNow you need to run the tests:\r\n<pre><code class=\"lang-bash\">.\/test_calculator\r\n<\/code><\/pre>\r\nSince all your tests pass successfully, this should exit without any output. You'll notice that two more files have been created, namely <code>test_calculator.gcda<\/code> and <code>calculator.gcda<\/code>. Similar to the <code>.gcno<\/code> files, the <code>gcda<\/code> files contain information related to the code coverage.\r\n<h3>Creating coverage reports<\/h3>\r\nNow that all the necessary files have been generated, you can run <code>gcov<\/code> to create the actual coverage report. You only want the coverage report of your library (<code>calculator.c<\/code>) and not the unit test file (<code>test_calculator.c<\/code>). So you'll run <code>gcov<\/code> on <code>calculator.c<\/code> only:\r\n<pre><code class=\"lang-bash\">gcov -pb caluclator.c <\/code><\/pre>\r\nHere are the explanations for the flags used:\r\n<pre><code><span class=\"hljs-keyword\">-b, <\/span>--<span class=\"hljs-keyword\">branch-probabilities <\/span>Include <span class=\"hljs-keyword\">branch <\/span>probabilities in output\r\n\r\n-p, --preserve-paths Preserve complete path information in the names of generated .gcov files.<\/code><\/pre>\r\nThis should give an output like the following:\r\n<pre><code>--&gt; gcov -pb calculator.c\r\nFile 'calculator.c'\r\nLines executed:83.33% of 12\r\nBranches executed:100.00% of 2\r\nTaken at least once:50.00% of 2\r\nNo calls\r\nCreating 'calculator.c.gcov'<\/code><\/pre>\r\nNow a file called <code>calculator.c.gcov<\/code> is created in the same directory. This file contains the detailed coverage report:\r\n<pre><code>--&gt; cat calculator.c.gcov\r\n -: 0:Source:calculator.c\r\n -: 0:Graph:calculator.gcno\r\n -: 0:Data:calculator.gcda\r\n -: 0:Runs:1\r\n -: 0:Programs:1\r\n -: 1:#include \r\n -: 2:\r\n -: 3:#include \"calculator.h\"\r\n -: 4:\r\nfunction add called 5 returned 100% blocks executed 100%\r\n 5: 5:double add(double x, double y) {\r\n 5: 6: return x + y;\r\n -: 7:}\r\n -: 8:\r\nfunction subtract called 6 returned 100% blocks executed 100%\r\n 6: 9:double subtract(double x, double y) {\r\n 6: 10: return x - y;\r\n -: 11:}\r\n -: 12:\r\nfunction multiply called 5 returned 100% blocks executed 100%\r\n 5: 13:double multiply(double x, double y) {\r\n 5: 14: return x * y;\r\n -: 15:}\r\n -: 16:\r\nfunction divide called 4 returned 100% blocks executed 75%\r\n 4: 17:double divide(double x, double y) {\r\n 4: 18: if (y == 0) {\r\nbranch 0 taken 0%\r\nbranch 1 taken 100%\r\n #####: 19: printf(\"Cannot divide by 0\");\r\n #####: 20: return 0;\r\n -: 21: }\r\n 4: 22: return x * 1.0 \/ y;\r\n 4: 23:}\r\n<\/code><\/pre>\r\nLet's take a quick minute to understand the report. Here each block is marked by a line with the same number as the last line of the block and the number of branches and calls in the block.\r\n\r\nNotice that you\u2019ve never called <code>divide<\/code> to divide by 0 in your test code. Hence the <code>if (y == 0) 0<\/code> branch was never executed. So, it says <code>#####<\/code> in that block.\r\n\r\nEach function in the report is preceded with a line stating how many times it was called, how many times it returned, and the percentage of blocks that were executed.\r\n\r\nFor example, the line <code>function add called 5 returned 100% blocks executed 100%<\/code> tells you that the function add was called 5 times. It returned 100% of the time and 100% of the blocks were executed.\r\n<h1 id=\"github-and-codecov\">GitHub and Codecov<\/h1>\r\nNow you'll set up Codecov with GitHub Actions. First, you'll create a GitHub repository and push your code there. Make sure to add the <code>*.gcno, *.gcda, *.gcov<\/code> and <code>test_calculator<\/code> executable in your <code>.gitignore<\/code>. These will be generated when the tests are run.\r\n\r\nNow you'll have to sign up for Codecov. So, navigate to <a href=\"https:\/\/codecov.io\">codecov.io<\/a> and click <strong>Sign Up<\/strong>. You can sign up with your GitHub account.\r\n\r\nOnce you do that, you'll see a list of your GitHub repositories. Choose the repository you just created to link it with Codecov. You will be presented with an upload token.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/04\/Aiv6Ue2.png\" alt=\"Codecov screen with the upload token redacted\" \/>\r\n\r\nYou\u2019ll need this token if your repository is private, or becomes private in the future.\r\n\r\nNow you'll create a GitHub Action. If you\u2019ve never worked with GitHub Actions, take a look at the <a href=\"https:\/\/docs.github.com\/en\/actions\">docs<\/a> first. The actions are just YAML files that need to be put in the <code>.github\/workflows<\/code> directory. Each YAML file will define an action. You can name these files anything you want.\r\n\r\nSo, create a file <code>.github\/workflows\/ci.yml<\/code> and enter this code:\r\n<pre><code class=\"lang-yaml\">name: Workflow for Codecov example-c\r\non: [push, pull_request]\r\njobs:\r\n run:\r\n runs-on: ubuntu-latest\r\n steps:\r\n - name: Checkout\r\n uses: actions\/checkout@v2\r\n - name: Compile calculator\r\n run: gcc -fprofile-arcs -ftest-coverage -O0 -o test_calculator test_calculator.c calculator.c\r\n - name: Run tests\r\n run: .\/test_calculator\r\n - name: Upload coverage to Codecov\r\n uses: codecov\/codecov-action@v3\r\n with:\r\n gcov: true\r\n gcov_include: calculator.c\r\n<\/code><\/pre>\r\nThis configuration tells GitHub that this action runs when you push to a branch or make a pull request. Then it defines a job named <code>run<\/code> with four steps:\r\n<ul>\r\n \t<li><code>Checkout<\/code>: Clones your repo.<\/li>\r\n \t<li><code>Compile caluclator<\/code>: Compiles the test code and generates the coverage report, just like you did locally.<\/li>\r\n \t<li><code>Run tests<\/code>: Runs the actual code<\/li>\r\n \t<li><code>Upload<\/code>: This is where the report is uploaded to Codecov. For that, we use the <a href=\"https:\/\/github.com\/codecov\/codecov-action\">codecov-action<\/a> action provided by Codecov.<\/li>\r\n<\/ul>\r\nNotice that we do not need to run a <code>gcov<\/code> step separately. The Codecov uploader can handle that with the <code>gcov<\/code> and <code>gcov_include<\/code> parameters.\r\n\r\nIf you have a private repo, you need to get the upload token from your Codecov dashboard and put it in a <a href=\"https:\/\/docs.github.com\/en\/actions\/reference\/encrypted-secrets\">GitHub encrypted secret<\/a>. Then you need to add another option to the <code>with<\/code> part in the GitHub Actions file:\r\n<pre><code class=\"lang-yaml\">...\r\n<span class=\"hljs-symbol\">with:<\/span>\r\n <span class=\"hljs-symbol\">token:<\/span> $<span class=\"hljs-template-variable\">{{ secrets.CODECOV_TOKEN }}<\/span>\r\n<\/code><\/pre>\r\nThis assumes that you named the secret <code>CODECOV_TOKEN<\/code>.\r\n\r\nNow commit and push the repository to GitHub. As soon as the push completes, the action will start to run. You can check the progress in the <code>Actions<\/code> tab in the GitHub repo.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/04\/RIHlLUT.png\" alt=\"Actions tab showing progress\" \/>\r\n\r\nWhen the action finishes completely, you'll see check marks by the names of the steps.\r\n\r\n<img class=\"alignnone size-full wp-image-8269\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/example-c.png\" alt=\"\" width=\"1266\" height=\"576\" \/>\r\n\r\nYou can check that the report was successfully uploaded to Codecov by expanding the <code>Upload<\/code> step.\r\n\r\n<img class=\"alignnone size-full wp-image-8270\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/upload-c.png\" alt=\"\" width=\"1416\" height=\"726\" \/>\r\n\r\nNow you can head over to your Codecov dashboard and navigate to your repository. You can also go to <code>https:\/\/codecov.io\/gh\/USER\/REPO<\/code> directly; just replace <code>USER<\/code> with your GitHub username, and <code>REPO<\/code> with your GitHub repo name. Now your coverage report should be visible in the dashboard.\r\n\r\n<img class=\"alignnone size-full wp-image-8271\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/dashboard.png\" alt=\"\" width=\"1145\" height=\"659\" \/>\r\n\r\nAt the bottom of the page, you'll see a sunburst graph and a file breakdown of your coverage. <img class=\"alignnone size-full wp-image-8272\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/sunburst.png\" alt=\"\" width=\"1161\" height=\"558\" \/>\r\n\r\n&nbsp;\r\n\r\nYou can read the <a href=\"https:\/\/docs.codecov.io\/docs\/graphs#sunburst\">docs<\/a> to learn how to navigate and use the sunburst graph.\r\n<h2 id=\"integrating-with-pull-requests\">Integrating with Pull Requests<\/h2>\r\nRemember, how you had one block that was not tested? Let's fix that and make a pull request.\r\n\r\nFirst, you'll create a new branch and make the changes in this new branch:\r\n<pre><code class=\"lang-bash\">git checkout -<span class=\"hljs-selector-tag\">b<\/span> divide-by-zero\r\n<\/code><\/pre>\r\nNow, open the <code>test_caluclator.c<\/code> file and remove the comment <code>\/\/<\/code> characters:\r\n<pre><code class=\"lang-c\"> assert(divide(2.0, 0) == 0.0);\r\n<\/code><\/pre>\r\nAdding this new <code>assert<\/code> statement will cause the previously unexecuted block to execute and should increase your coverage.\r\n\r\nSo, push the changes to a new branch:\r\n<pre><code class=\"lang-bash\">git add test_calculator.c\r\ngit commit -m 'fix: improve code coverage'\r\ngit push origin divide-by-zero<\/code><\/pre>\r\nNow create a pull request from this new branch to the main branch. When you create the pull request, the action will be run and generate your coverage report.\r\n\r\n<img class=\"alignnone size-full wp-image-8273\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/run.png\" alt=\"\" width=\"847\" height=\"673\" \/>\r\n\r\nWhen the checks are successful, the Codecov bot will comment with a coverage report that shows how the coverage will change due to the pull request.\r\n\r\n<img class=\"alignnone size-full wp-image-8274\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/comment.png\" alt=\"\" width=\"829\" height=\"562\" \/>\r\n\r\nIn this case, you can see that it says <code>calculator.c<\/code> will have its coverage increased to 100%, as you had guessed.\r\n\r\nYou can visit the <strong>Pulls<\/strong> tab in your Codecov dashboard to check the coverage for all the pull requests ever made.\r\n\r\n<img class=\"alignnone size-full wp-image-8275\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/pulls.png\" alt=\"\" width=\"1047\" height=\"326\" \/>\r\n\r\nHere you can select the pull request, and you'll get access to the detailed coverage changes, similar to the comment.\r\n\r\n<img class=\"alignnone size-full wp-image-8276\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/pull.png\" alt=\"\" width=\"1168\" height=\"700\" \/>\r\n\r\nYou can visit the <strong>Commits<\/strong> tab where you can access the coverage for individual commits.\r\n\r\n<img class=\"alignnone size-full wp-image-8278\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/05\/commits.png\" alt=\"\" width=\"1050\" height=\"327\" \/>\r\n\r\nThe 100% in pink indicates the coverage for the total project, and the percentage in green tells you that the coverage increased by 15.00% after this commit.\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nIn this tutorial, you learned about how code coverage is important for identifying portions of your code that are not covered by the unit tests. Code coverage lets you understand where your unit tests are lacking and helps you detect bugs early.\r\n\r\nYou also learned how to set up testing for your C code locally using Gcov and how to integrate <a href=\"https:\/\/about.codecov.io\/demo\/\">Codecov<\/a> with your GitHub repository using GitHub Actions and generate coverage reports for each commit and pull request.","post_title":"How to Set Up Codecov with C and GitHub Actions in 2022","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"how-to-set-up-codecov-with-c-and-github-actions","to_ping":"","pinged":"","post_modified":"2023-05-23 08:56:30","post_modified_gmt":"2023-05-23 13:56:30","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=4668","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[53],"tools":[230],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/08042022_How-to-Set-Up-Codecov-with-C-and-GitHub-Actions-in-2022-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/08042022_How-to-Set-Up-Codecov-with-C-and-GitHub-Actions-in-2022-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/how-to-set-up-codecov-with-c-and-github-actions\/","authorID":"39","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/04\/1602422364613.jpeg","authorDisplayName":"Aniket Bhattacharyea","authorURL":"https:\/\/www.linkedin.com\/in\/heraldofsolace\/","cta":"Read Blog Post"},{"ID":6522,"post_author":"67","post_date":"2021-11-30 14:12:57","post_date_gmt":"2021-11-30 18:12:57","post_content":"You may not be familiar yet with <a href=\"https:\/\/copilot.github.com\/\">GitHub Copilot<\/a>, which was launched by GitHub in collaboration with OpenAI in July 2021. The AI pair programmer powered by Codex suggests lines of code and functions based on the comments and code it reads in your project.\r\n\r\nThe model used by Copilot has been trained on the source code available in public GitHub repos, but as more and more people use it, Copilot will get smarter with time.\r\n\r\nThis article will go through how GitHub Copilot works and why you might want to use it to optimize your testing process.\r\n<h2 id=\"how-copilot-works\">How Copilot Works<\/h2>\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/rDvb4Dn.gif\" alt=\"Copilot writing a function\" \/>\r\n\r\nAbove is GitHub Copilot in action. You write the docstring or the comment, and it suggests a code snippet. In some cases, just the function name or a part of the function is enough for it to generate the rest of the code. The code is uniquely generated for you, and you own it.\r\n\r\nBelow is a high-level overview of how it works:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/6p61HYK.png\" alt=\"Work process, courtesy of Copilot\" \/>\r\n\r\nCopilot makes ten suggestions at a time. As you type more code, the suggestions will become more accurate.\r\n<h2 id=\"how-to-access-copilot\">How to Access Copilot<\/h2>\r\nCopilot is undergoing a technical preview and is available to a limited number of developers. You can join the waitlist <a href=\"https:\/\/github.com\/features\/copilot\/signup\">here<\/a>.\r\n\r\nThe only IDE or editor currently supported by Copilot is <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a>. You would only need to install the Copilot extension and enter your GitHub credentials.\r\n<h2 id=\"why-use-copilot\">Why Use Copilot<\/h2>\r\nThe goal of Copilot is to increase an engineer\u2019s productivity. Copilot can save you the trouble of writing repetitive code and can help you work faster by saving you the time spent searching for code syntax. It can also suggest code using third-party APIs or libraries. It supports Python, JavaScript, Ruby, TypeScript, and Go; it can also be useful in writing test cases.\r\n<h2 id=\"demo-application\">Demo Application<\/h2>\r\nThis article uses a demo application with unit test cases written by Copilot. The functionality of each test will be written as a docstring, and Copilot will have about five seconds each time to generate code.\r\n\r\nThe application will be a basic API wrapper for the <a href=\"https:\/\/jsonplaceholder.typicode.com\/\">JSONPlaceholder API<\/a>. The code will be written in Python. The API wrapper will have functions to make various HTTP requests to the available endpoint.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/SBMJ1Vg.gif\" alt=\"Coding the API wrapper\" \/>\r\n\r\nAs you can see, most of the code was written by Copilot, including suggested endpoints. It also chose good function names and used the snake_case. The post method was able to predict the correct schema for the body of the request. However, it made a mistake. The route for the function <code>get_comment()<\/code> was incorrect. The correct route is <code>\/posts\/1\/comments<\/code> or <code>\/comments?postId=1<\/code>. Copilot suggested the route to be <code>(self.url + '\/posts\/' + str(comment_id)).json() + '\/comments'<\/code>. It got the structure of the URL incorrect as well since it tried to append <code>\/comments<\/code> after getting the JSON data.\r\n<h3 id=\"unit-tests\">Unit Tests<\/h3>\r\nNow Copilot will write unit tests for the wrapper functions. This tests each of your functions in a standalone environment.\r\n\r\nTo avoid duplicate work, I will write a few testing functions rather than test all the GET request functions.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/RQyx9LW.gif\" alt=\"Copilot generating code for testing GET requests\" \/>\r\n\r\nAs you can see, again, most of the code was written by Copilot. The test functions were written in a separate file, and Copilot was able to correctly link the API wrapper.\r\n\r\nLet\u2019s discuss the code written for each function.\r\n<h4 id=\"test_get_posts\">test_get_posts<\/h4>\r\nCopilot got everything correct except for the key <code>username<\/code>, which doesn\u2019t exist in the response object.\r\n<h4 id=\"test_get_post\">test_get_post<\/h4>\r\nAgain, Copilot added a check for username, although that key doesn\u2019t exist.\r\n<h4 id=\"test_get_comments\">test_get_comments<\/h4>\r\nCopilot got this completely wrong. It did not pass the required parameter and somehow predicted the length of the response object to be 10. Additionally, if you look at the GIF, you will notice it stopped predicting after the <code>==<\/code>. This could have caused a syntax error.\r\n\r\nNow let\u2019s look at the post, put, and delete methods.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/9oAgy3F.gif\" alt=\"Post, put, and delete functions\" \/>\r\n\r\nHere is the code generated for each function.\r\n<h4 id=\"test_make_post\">test_make_post<\/h4>\r\nFor this function, I wrote <code>test_make_post<\/code> instead of <code>test_create_post<\/code>. Copilot ended up calling <code>api.make_post()<\/code> instead of <code>api.create_post()<\/code>, although <code>api<\/code> has no method called <code>make_post()<\/code>. It forgot to pass the user ID parameter as well, although it correctly predicted that the ID of the new post would be 101.\r\n<h4 id=\"test_update_post\">test_update_post<\/h4>\r\nCopilot got everything correct except for the check for userID. The response object doesn\u2019t contain any key called \u201cuserId\u201d.\r\n<h4 id=\"test_delete_post\">test_delete_post<\/h4>\r\nThe response object is empty, but Copilot made some unnecessary checks.\r\n<h3 id=\"better-tests\">Better Tests<\/h3>\r\nIn all the above test functions, Copilot wrote the docstring and the code. For you to get more accurate results, it is better to write your own docstrings and function definitions. We will try to mimic a user\u2019s behavior and write a couple of integration tests. Integration tests validate multiple tests together, helping you ensure a new feature doesn\u2019t break an existing feature. When doing integration tests, we try to simulate real-time behavior. Below, we run an integration test to mimic a user\u2019s behavior:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/NF6BflI.gif\" alt=\"Copilot writing integration tests\" \/>\r\n\r\nThe code generated this time was more documented. Copilot basically suggested the same code snippet it suggested for each of the unit test functions, and instead of making a GET request to check if the posts had been created or updated, it used an assert statement on the response object.\r\n\r\nInstead of using the entire code suggested by Copilot, you could use a part of it or make the docstring more extensive. Behavior-driven development (BDD) or Given-When-Then testing will help you write better docstrings.\r\n<h3 id=\"behavior-driven-development\">Behavior-Driven Development<\/h3>\r\nThe idea is to break down your test into the following format:\r\n<ul>\r\n \t<li>given: describe the current state of the world<\/li>\r\n \t<li>when: describe the behavior<\/li>\r\n \t<li>then: describe the expected behavior<\/li>\r\n<\/ul>\r\nIn the case of the API wrapper, a test case using BDD could be as follows:\r\n<pre><code>given I make a <span class=\"hljs-keyword\">DELETE<\/span> request <span class=\"hljs-keyword\">to<\/span> Deleted a Post\r\n<span class=\"hljs-keyword\">when<\/span> The Post <span class=\"hljs-keyword\">ID<\/span> <span class=\"hljs-keyword\">is<\/span> <span class=\"hljs-keyword\">Empty<\/span>\r\n<span class=\"hljs-keyword\">then<\/span> API wrapper should <span class=\"hljs-keyword\">return<\/span> an <span class=\"hljs-keyword\">error<\/span>\r\n<\/code><\/pre>\r\nNow let\u2019s try writing this as a docstring using Copilot.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/3HP5KWG.gif\" alt=\"Delete\" \/>\r\n\r\nAlthough Copilot added extra docstrings, it got the code correct. I didn\u2019t specify the type of error in my docstring, so it checked for a ValueError, which makes sense.\r\n\r\nLet\u2019s try rewriting the unit test case for <code>test_delete_post<\/code> using BDD:\r\n<pre><code>given I make a <span class=\"hljs-keyword\">Delete<\/span> request <span class=\"hljs-keyword\">to<\/span> <span class=\"hljs-keyword\">Delete<\/span> a Post\r\n<span class=\"hljs-keyword\">when<\/span> the Post <span class=\"hljs-keyword\">ID<\/span> <span class=\"hljs-keyword\">is<\/span> successfully deleted\r\n<span class=\"hljs-keyword\">then<\/span> API wrapper should <span class=\"hljs-keyword\">return<\/span> an <span class=\"hljs-keyword\">empty<\/span> <span class=\"hljs-keyword\">object<\/span>\r\n<\/code><\/pre>\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/LMzD10V.gif\" alt=\"Delete\" \/>\r\n\r\nIn this case, it added the correct assert statement since we explicitly specified it.\r\n\r\nLet\u2019s write a BDD test case for the update request:\r\n<pre><code>given I make an <span class=\"hljs-keyword\">Update<\/span> request <span class=\"hljs-keyword\">with<\/span> a Post <span class=\"hljs-keyword\">ID<\/span>\r\n<span class=\"hljs-keyword\">when<\/span> the Post <span class=\"hljs-keyword\">is<\/span> successfully <span class=\"hljs-keyword\">updated<\/span>\r\n<span class=\"hljs-keyword\">then<\/span> a <span class=\"hljs-keyword\">Get<\/span> request <span class=\"hljs-keyword\">with<\/span> Post <span class=\"hljs-keyword\">ID<\/span> should <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">updated<\/span> <span class=\"hljs-keyword\">object<\/span>\r\n<\/code><\/pre>\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/7vG8pqg.gif\" alt=\"Update\" \/>\r\n\r\nIn this case, the tester function was supposed to make a GET request to ensure that the post had been updated. However, the code generated by Copilot used assert statements on the assert statement. After I changed the first assert statement, it was able to predict the rest.\r\n\r\nThis just shows that Copilot is not perfect. You will have to verify that the code it generates is suitable for your use case.\r\n<h3 id=\"copilot-s-weaknesses-and-strengths\">Copilot\u2019s Weaknesses and Strengths<\/h3>\r\nBy now, you must have already noticed some of Copilot\u2019s weaknesses. In most cases, your docstrings have to be explicit. Since Copilot doesn\u2019t have any context and can\u2019t mimic user behavior, you will still have to think of edge cases to test and how to test them. The code Copilot generates will, in some cases, lead to syntax errors, so you will have to verify it.\r\n\r\nCopilot also has its strengths. Among them is generating data sets.\r\n\r\nBelow is the docstring for the function:\r\n<pre><code><span class=\"hljs-number\">1.<\/span> Function <span class=\"hljs-built_in\">to<\/span> <span class=\"hljs-built_in\">create<\/span> <span class=\"hljs-number\">100<\/span> <span class=\"hljs-built_in\">random<\/span> users <span class=\"hljs-keyword\">using<\/span> faker library\r\n<span class=\"hljs-number\">2.<\/span> Each user should have between <span class=\"hljs-number\">1<\/span> <span class=\"hljs-keyword\">and<\/span> <span class=\"hljs-number\">5<\/span> posts\r\n<span class=\"hljs-number\">3.<\/span> The user <span class=\"hljs-keyword\">and<\/span> <span class=\"hljs-keyword\">the<\/span> <span class=\"hljs-built_in\">post<\/span> should be sent <span class=\"hljs-built_in\">to<\/span> <span class=\"hljs-keyword\">the<\/span> API via <span class=\"hljs-keyword\">a<\/span> <span class=\"hljs-built_in\">post<\/span> request\r\n<\/code><\/pre>\r\nFaker is a Python library that generates fake data. It can be used to populate databases, get random data, or create fake user profiles. You can find the repo <a href=\"https:\/\/github.com\/joke2k\/faker\">here<\/a>.\r\n\r\nWatch Copilot and Faker in action:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/rbVhVpH.gif\" alt=\"Data set function\" \/>\r\n\r\nNotice how Copilot used <code>max_chars<\/code> 50 for the title and 200 for the body. It also chose a random number of posts per user and correctly associated the posts with the user.\r\n\r\nThere are some limitations, however. In some cases, it is hard to specify the schema. If you do not reference the API wrapper, Copilot adds <code>email<\/code> and <code>dob<\/code> to the schema as well. When I mentioned the schema in the docstring, it didn\u2019t generate fake names.\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nCopilot can increase your productivity and save you time when writing repetitive code. You do need to closely monitor Copilot\u2019s output in some cases. Although most of my time was spent writing docstrings for the functions, I did have to modify some of the code Copilot generated.\r\n\r\nHowever, when testing multiple GET requests or similar functions, Copilot was able to generate most of the tests required. This means integrating Copilot into your workflow once it\u2019s fully available could be well worth the effort.","post_title":"Writing Better Tests with AI and GitHub Copilot","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"writing-better-tests-with-ai-and-github-copilot","to_ping":"","pinged":"","post_modified":"2021-11-30 14:33:13","post_modified_gmt":"2021-11-30 18:33:13","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=6522","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":false,"tools":[241,70],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/30.-Writing-Better-Tests-With-AI-and-GitHub-Copilot-v2-01.png","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/30.-Writing-Better-Tests-With-AI-and-GitHub-Copilot-v2-01.png","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/writing-better-tests-with-ai-and-github-copilot\/","authorID":"67","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/11\/profilePic-RahulBanerjee.jpeg","authorDisplayName":"Rahul Banerjee","authorURL":"https:\/\/www.linkedin.com\/in\/rahulbanerjee2699\/","cta":"Read Blog Post"},{"ID":6297,"post_author":"7","post_date":"2021-11-30 13:17:14","post_date_gmt":"2021-11-30 17:17:14","post_content":"<span style=\"font-weight: 400;\">In this tutorial, we will set up a project that uses Codefresh Pipelines to send coverage reports to Codecov. You will learn how to do the following:<\/span>\r\n<ol>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Set up a <\/span><a href=\"https:\/\/codefresh.io\/docs\/docs\/getting-started\/create-a-basic-pipeline\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codefresh Pipeline<\/span><\/a><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Utilize Codefresh\u2019s platform to integrate with Codecov for coverage reports send coverage reports to Codecov<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Read coverage reports on Codecov\u2019s UI<\/span><\/li>\r\n<\/ol>\r\n<span style=\"font-weight: 400;\">To get started with this tutorial, you will need a <\/span><a href=\"https:\/\/codefresh.io\/codefresh-signup\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codefresh<\/span><\/a><span style=\"font-weight: 400;\"> and <\/span><a href=\"https:\/\/about.codecov.io\/sign-up\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codecov<\/span><\/a><span style=\"font-weight: 400;\"> account. We will be using Codecov\u2019s <\/span><a href=\"https:\/\/github.com\/codecov\/example-python\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">example python repository<\/span><\/a><span style=\"font-weight: 400;\">, which you can clone into a GitHub account. You should still be able to follow along with your own repository if it is already running tests and collecting coverage.<\/span>\r\n\r\n<b>Intro to Codefresh<\/b>\r\n\r\n<span style=\"font-weight: 400;\">Codefresh is an enterprise GitOps platform specifically for Kubernetes applications. It allows you to build, test, integrate, and deploy your product with unlimited scalability, speed, advanced caching, parallel steps and pipelines, in addition to providing end-to-end <\/span><a href=\"https:\/\/codefresh.io\/gitops\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">GitOps<\/span><\/a><span style=\"font-weight: 400;\"> support.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">Codefresh also provides Argo CD, Argo Rollouts, Argo Workflows, and Argo Events for the enterprise with the\u00a0<a href=\"https:\/\/codefresh.io\/codefresh-argo-platform\/\" target=\"_blank\" rel=\"noopener\" data-saferedirecturl=\"https:\/\/www.google.com\/url?q=https:\/\/codefresh.io\/codefresh-argo-platform\/&amp;source=gmail&amp;ust=1635521519498000&amp;usg=AFQjCNFA_IzmR0X97nXX7IpufMWbIipZ6g\">Codefresh DevOps Platform for Argo<\/a>. This will enable teams to manage and monitor\u00a0<a href=\"https:\/\/codefresh.io\/argo-codefresh\/\" target=\"_blank\" rel=\"noopener\" data-saferedirecturl=\"https:\/\/www.google.com\/url?q=https:\/\/codefresh.io\/argo-codefresh\/&amp;source=gmail&amp;ust=1635521519498000&amp;usg=AFQjCNEkpgD6nLG5mHr2Azg4YJk0xxZSJA\">Argo<\/a> at an enterprise scale.\u00a0<\/span><span style=\"font-weight: 400;\">This includes:<\/span>\r\n<ul>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Simplifying blue\/green and canary deployments.<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">A GitOps dashboard connecting you to your deployments, commits, tests, tickets, logging, and more.<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Monitoring for configuration drift.<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Current and desired state views for environments.<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">One-click Argo bootstrapping and installation through Codefresh.<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Management and monitoring of multiple Argo CD installations.<\/span><\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\n<b>Step 0: Setting up the example repository<\/b>\r\n\r\n<span style=\"font-weight: 400;\">For users following along with our example repository, you can fork it by going to <\/span><a href=\"https:\/\/github.com\/codecov\/example-python\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">https:\/\/github.com\/codecov\/example-python<\/span><\/a><span style=\"font-weight: 400;\"> and clicking on <code>Fork<\/code> in the top right.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6298\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image3.png\" alt=\"\" width=\"953\" height=\"689\" \/>\r\n\r\n<span style=\"font-weight: 400;\">You may then be given the choice to choose which organization to clone the repository. We recommend choosing your own user account.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">You can then sign into Codecov and enable the repository. Go to <\/span><a href=\"https:\/\/codecov.io\/gh\/\"><span style=\"font-weight: 400;\">https:\/\/codecov.io\/gh\/<\/span><\/a><span style=\"font-weight: 400;\">{{ YOUR USERNAME }} and look for your repository in the <code>Not yet setup<\/code> section.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6313\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image16.png\" alt=\"\" width=\"1054\" height=\"443\" \/>\r\n\r\n<span style=\"font-weight: 400;\">If you are having trouble seeing the repository, you can try clicking <code>re-syncing<\/code> or follow instructions on <\/span><a href=\"https:\/\/docs.codecov.com\/docs\/github-oauth-application-authorization\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">granting GitHub oauth application authorization<\/span><\/a><span style=\"font-weight: 400;\">.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">When you find the repository, click <code>setup repo<\/code> to activate it.<\/span>\r\n\r\n&nbsp;\r\n\r\n<b>Step 1: Getting your Codecov token<\/b>\r\n\r\n<span style=\"font-weight: 400;\">After activating, you should be on the repository dashboard page. You should see the Codecov token located at step 1. Click <code>Copy<\/code> to copy the token. This token is used to verify and authenticate uploads to Codecov.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6305\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image8.png\" alt=\"\" width=\"972\" height=\"566\" \/>\r\n\r\n<span style=\"font-weight: 400;\">If you already have uploaded coverage reports to Codecov, you can find the token in the Settings tab.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6303\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image6.png\" alt=\"\" width=\"990\" height=\"460\" \/>\r\n\r\n<b>Step 2: Integrating Codecov with Codefresh<\/b>\r\n\r\n&nbsp;\r\n\r\n<span style=\"font-weight: 400;\">With the token in hand, head over to <\/span><a href=\"https:\/\/codefresh.io\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codefresh<\/span><\/a><span style=\"font-weight: 400;\">. If you haven\u2019t created a Codefresh account yet, you will need to do so to continue this tutorial.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">First, go to your account settings on the navigation bar<\/span>\r\n\r\n[caption id=\"attachment_6311\" align=\"alignnone\" width=\"220\"]<img class=\"wp-image-6311\" style=\"width: 231px important!;\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image14.png\" alt=\"\" width=\"220\" height=\"691\" \/> .[\/caption]\r\n\r\n<span style=\"font-weight: 400;\">Then, click on <code>Integrations<\/code> on the same navigation bar. Scroll down until you see <code>Codecov<\/code>, and click <code>Configure<\/code>.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6316\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image19.png\" alt=\"\" width=\"1107\" height=\"747\" \/>\r\n\r\n<span style=\"font-weight: 400;\">Click <code>Add Integration<\/code> to copy over the Codecov token.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6315\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image18.png\" alt=\"\" width=\"1107\" height=\"639\" \/>\r\n\r\n<span style=\"font-weight: 400;\">You will need a separate integration for each repository you set up. We recommend filling the <code>Integration Name<\/code> field with this name of the repository. You should copy the Codecov token into the <code>Token<\/code> field. When done, click <code>Test connection<\/code> and <code>Save<\/code>.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6300\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image2.png\" alt=\"\" width=\"1105\" height=\"664\" \/>\r\n\r\n<span style=\"font-weight: 400;\">You should see the integration saved in the dashboard.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6306\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image9.png\" alt=\"\" width=\"1108\" height=\"377\" \/>\r\n\r\n<b>Step 3: Creating a Codefresh Pipeline<\/b>\r\n\r\n<span style=\"font-weight: 400;\">Navigate back out of Account Settings and click into Pipelines. You can also go directly at <\/span><a href=\"https:\/\/g.codefresh.io\/pipelines\/all\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">https:\/\/g.codefresh.io\/pipelines\/all\/<\/span><\/a><span style=\"font-weight: 400;\">\u00a0<\/span>\r\n\r\n[caption id=\"attachment_6319\" align=\"alignnone\" width=\"227\"]<img class=\"wp-image-6319\" style=\"width: 227px important!;\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image22.png\" alt=\"\" width=\"227\" height=\"273\" \/> .[\/caption]\r\n\r\n<span style=\"font-weight: 400;\">Select <code>New Pipeline<\/code> to create a new pipeline.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6314\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image17.png\" alt=\"\" width=\"1110\" height=\"371\" \/>\r\n\r\n<span style=\"font-weight: 400;\">Pipelines do not necessarily have to be tied to a repository and have flexible naming. You will likely need to create a default project, but you can name your pipeline whatever makes sense for your project. For this tutorial, we recommend adding a git repository. When you are finished, click <code>Create<\/code><\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6312\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image15.png\" alt=\"\" width=\"612\" height=\"688\" \/>\r\n<span style=\"font-weight: 400;\">You should now be taken to a screen to set up the workflow.<\/span>\r\n\r\n&nbsp;\r\n\r\n<b>Step 4: Setting up the Codefresh pipeline with Codecov<\/b>\r\n<pre class=\"hljs yaml\"><code><span style=\"font-weight: 400;\">The default YAML in display should look like this:<\/span>\r\n\r\n\u200b\u200b# More examples of Codefresh YAML can be found at\r\n# https:\/\/codefresh.io\/docs\/docs\/yaml-examples\/examples\/\r\n\r\nversion: \"1.0\"\r\n# Stages can help you organize your steps in stages\r\nstages:\r\n\u00a0 - \"clone\"\r\n\u00a0 - \"build\"\r\n\u00a0 - \"test\"\r\n\r\nsteps:\r\n\u00a0 clone:\r\n\u00a0 \u00a0 title: \"Cloning repository\"\r\n\u00a0 \u00a0 type: \"git-clone\"\r\n\u00a0 \u00a0 repo: \"thomasrockhu-codecov\/example-python\"\r\n\u00a0 \u00a0 # CF_BRANCH value is auto set when pipeline is triggered\r\n\u00a0 \u00a0 # Learn more at codefresh.io\/docs\/docs\/codefresh-yaml\/variables\/\r\n\u00a0 \u00a0 revision: \"${{CF_BRANCH}}\"\r\n\u00a0 \u00a0 git: \"github\"\r\n\u00a0 \u00a0 stage: \"clone\"\r\n\r\n\u00a0 build:\r\n\u00a0 \u00a0 title: \"Building Docker image\"\r\n\u00a0 \u00a0 type: \"build\"\r\n\u00a0 \u00a0 image_name: \"thomasrockhu-codecov\/example-python\"\r\n\u00a0 \u00a0 working_directory: \"${{clone}}\"\r\n\u00a0 \u00a0 tag: \"${{CF_BRANCH_TAG_NORMALIZED}}\"\r\n\u00a0 \u00a0 # If you have a Dockerfile in the repo you can use\r\n\u00a0 \u00a0 # dockerfile: 'Dockerfile'\r\n\u00a0 \u00a0 dockerfile:\r\n\u00a0 \u00a0 \u00a0 content: \"FROM python:onbuild\\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 WORKDIR \/root\/onboarding\\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 COPY . \/\"\r\n\u00a0 \u00a0 stage: \"build\"\r\n\r\n\u00a0 test:\r\n\u00a0 \u00a0 title: \"Running test\"\r\n\u00a0 \u00a0 type: \"freestyle\" # Run any command\r\n\u00a0 \u00a0 image: \"ubuntu:latest\" # The image in which command will be executed\r\n\u00a0 \u00a0 working_directory: \"${{clone}}\" # Running command where code cloned\r\n\u00a0 \u00a0 commands:\r\n\u00a0 \u00a0 \u00a0 - \"ls\"\r\n\u00a0 \u00a0 stage: \"test\"\r\n<\/code><\/pre>\r\n<span style=\"font-weight: 400;\">You will need to change <code>test<\/code> step of the yaml to read:<\/span>\r\n<pre class=\"hljs yaml\"><code>\u00a0 test:\r\n\u00a0 \u00a0 title: \"Running test\"\r\n\u00a0 \u00a0 type: \"freestyle\" # Run any command\r\n\u00a0 \u00a0 image: \"python:3.9-slim\" # The image in which command will be executed\r\n\u00a0 \u00a0 working_directory: \"${{clone}}\" # Running command where code cloned\r\n\u00a0 \u00a0 commands:\r\n\u00a0 \u00a0 \u00a0 - pip install -r requirements.txt\r\n\u00a0 \u00a0 \u00a0 - coverage run tests.py\r\n\u00a0 \u00a0 \u00a0 - coverage xml\r\n\u00a0 \u00a0 stage: \"test\"\r\n<\/code><\/pre>\r\n<span style=\"font-weight: 400;\">Note: Only the <code>image<\/code> and <code>commands<\/code> sections have changed within the \u2018test\u2019 step. When you are finished, click <code>Save<\/code> and <code>Run<\/code>. You will be asked to trigger a run. The default settings should be good enough to run the pipeline.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6308\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image11.png\" alt=\"\" width=\"632\" height=\"490\" \/>\r\n\r\n<span style=\"font-weight: 400;\">You can view the output to confirm when the pipeline build has completed. You should see all three steps complete successfully. Clicking into the <code>test<\/code> step will show all tests have successfully passed.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6307\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image10.png\" alt=\"\" width=\"1113\" height=\"815\" \/>\r\n\r\n<span style=\"font-weight: 400;\">We will now need to upload coverage reports to Codecov.<\/span>\r\n\r\n&nbsp;\r\n\r\n<b>Step 5: Uploading coverage reports to Codecov<\/b>\r\n\r\n<span style=\"font-weight: 400;\">Click to edit the pipeline<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6299\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image1.png\" alt=\"\" width=\"1114\" height=\"268\" \/>\r\n\r\n<span style=\"font-weight: 400;\">In the right section, you can search for the Codecov step in the Marketplace.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6310\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image13.png\" alt=\"\" width=\"1117\" height=\"432\" \/>\r\n\r\n<span style=\"font-weight: 400;\">Clicking the <code>codecov-reporter<\/code> step will open a modal to copy the step.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6301\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image4.png\" alt=\"\" width=\"933\" height=\"624\" \/>\r\n\r\n<span style=\"font-weight: 400;\">After copying, click <code>Cancel<\/code> to leave the modal. Paste the step into your pipeline YAML, and note that the code may need to be indented properly. Also, the <code>codecov_integration<\/code> should be replaced with the name created in step 2.<\/span>\r\n<pre class=\"hljs yaml\"><code>\u00a0 codecov-report:\r\n\u00a0 \u00a0 title: Codecov report\r\n\u00a0 \u00a0 type: codecov-reporter\r\n\u00a0 \u00a0 arguments:\r\n\u00a0 \u00a0 \u00a0 codecov_integration: example-python\r\n\u00a0 \u00a0 stage: \"test\"\r\n<\/code><\/pre>\r\n<img class=\"alignnone size-full wp-image-6309\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image12.png\" alt=\"\" width=\"1253\" height=\"803\" \/>\r\n<span style=\"font-weight: 400;\">Click save and run the pipeline again. We should now see 4 steps in the pipeline. Click the <code>Codecov report<\/code> step when the pipeline has finished running.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">In the console, you should see a line exporting <code>second_CF_OUTPUT_URL<\/code>. Copy that URL to view coverage reports on Codecov.<\/span>\r\n\r\n&nbsp;\r\n\r\n<b>Step 6: Viewing coverage data on Codecov<\/b>\r\n\r\n<span style=\"font-weight: 400;\">Navigating to the URL will land you on the commit page on Codecov. Note that since this is our first coverage report for our first commit, there is no diff to compare against. Clicking on the <code>Files<\/code> tab will show us the coverage for our files.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6318\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image21.png\" alt=\"\" width=\"982\" height=\"693\" \/>\r\n\r\n<span style=\"font-weight: 400;\">Opening <code>awesome\/__init__.py<\/code> shows us that we have fully tested the <code>smile<\/code> function, while <code>frown<\/code> has remained uncovered.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6304\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image7.png\" alt=\"\" width=\"1055\" height=\"372\" \/>\r\n\r\n<span style=\"font-weight: 400;\">We can do better than just 75% for this file.<\/span>\r\n\r\n&nbsp;\r\n\r\n<b>Step 7: Adding tests to increase code coverage<\/b>\r\n\r\n<span style=\"font-weight: 400;\">To cover the <code>frown<\/code> function, let\u2019s add a test to our <code>tests.py<\/code> file. In your favorite IDE, update the file to read\r\n<\/span>\r\n<pre class=\"hljs yaml\"><code>import unittest\r\n\r\nimport awesome\r\n\r\n\r\nclass TestMethods(unittest.TestCase):\r\n\u00a0 \u00a0 def test_add(self):\r\n\u00a0 \u00a0 \u00a0 \u00a0 self.assertEqual(awesome.smile(), \":)\")\r\n\r\n\u00a0 \u00a0 def test_frown(self):\r\n\u00a0 \u00a0 \u00a0 \u00a0 self.assertEqual(awesome.frown(), \":(\")\r\n\r\n\r\nif __name__ == '__main__':\r\n\u00a0 \u00a0 unittest.main()\r\n<\/code><\/pre>\r\n<span style=\"font-weight: 400;\">Note the new <code>test_frown<\/code> function. Create a new branch and push the change to your git provider. Codefresh will automatically pick up the change and begin running your pipeline. You can view the <\/span><a href=\"https:\/\/github.com\/thomasrockhu-codecov\/example-python\/pull\/1\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">tutorial pull request<\/span><\/a><span style=\"font-weight: 400;\">.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">You will notice that when the Codefresh pipeline has completed that both Codecov and Codefresh add status checks<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6317\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image20.png\" alt=\"\" width=\"810\" height=\"394\" \/>\r\n\r\n<span style=\"font-weight: 400;\">The <code>codecov\/project<\/code> status tells us that we have covered 100% of the codebase. The <code>codecov\/patch<\/code> status tells us that all new code is also 100% covered. You can read more about statuses in our <\/span><a href=\"https:\/\/docs.codecov.com\/docs\/commit-status\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">documentation<\/span><\/a><span style=\"font-weight: 400;\">.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">You will also notice that Codecov has added a comment that details coverage change information. This is useful for the author and reviewers of the PR.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6302\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/image5.png\" alt=\"\" width=\"744\" height=\"687\" \/>\r\n\r\n<span style=\"font-weight: 400;\">We can click back into the Codecov report above to see that we have fully covered the <code>awesome\/__init__.py<\/code> file.<\/span>\r\n\r\n<hr class=\"wp-block-separator\" \/>\r\n\r\n<span style=\"font-weight: 400;\">At the end of this tutorial, you will have<\/span>\r\n<ol>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">set up a Codefresh pipeline<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">viewed coverage reports on Codecov<\/span><\/li>\r\n \t<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">added a test to increase coverage through Codecov<\/span><\/li>\r\n<\/ol>\r\n<span style=\"font-weight: 400;\">If you have any questions or comments for the community, please share those below.<\/span>\r\n\r\n&nbsp;","post_title":"Getting started with Codefresh and Codecov","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"getting-started-with-codefresh-and-codecov","to_ping":"","pinged":"","post_modified":"2021-11-30 13:17:39","post_modified_gmt":"2021-11-30 17:17:39","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=6297","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":false,"tools":[289,241],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/Codeov-and-Codefresh-md.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/10\/Codeov-and-Codefresh-md.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/getting-started-with-codefresh-and-codecov\/","authorID":"7","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/tom-hu.png","authorDisplayName":"Tom Hu","authorURL":"https:\/\/www.linkedin.com\/in\/thomasrockhu\/","cta":"Read Blog Post"},{"ID":6001,"post_author":"59","post_date":"2021-09-09 10:17:23","post_date_gmt":"2021-09-09 14:17:23","post_content":"<a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_coverage\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Code Coverage<\/span><\/a><span style=\"font-weight: 400;\"> is a measure of how much of your code has been executed. It is typically presented as a <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\/index.html?subfolder=\/manual\/HowToInterpretResults.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">report<\/span><\/a><span style=\"font-weight: 400;\"> that shows the percentage of the code that has been executed. For automated testing, the report does not measure the quality of tests, only whether your code is executed by the tests. It is especially useful to check that critical or high-risk areas of your code are covered because they should receive the most rigorous testing.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">In Unity, the <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Code Coverage package<\/span><\/a><span style=\"font-weight: 400;\"> generates code coverage data and reports from your automated tests. Additionally, the Code Coverage package offers a <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\/index.html?subfolder=\/manual\/CoverageRecording.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Coverage Recording<\/span><\/a><span style=\"font-weight: 400;\"> feature that allows capturing coverage data on demand, for manual testing, or when there are no automated tests in the project.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">In this tutorial, you will learn how to set up code coverage in a Unity project using the Code Coverage package and how to integrate <\/span><a href=\"https:\/\/about.codecov.io\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codecov<\/span><\/a><span style=\"font-weight: 400;\"> with your GitHub repository using <\/span><a href=\"https:\/\/github.com\/features\/actions\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">GitHub Actions<\/span><\/a><span style=\"font-weight: 400;\"> to generate coverage reports every time you push changes or make a pull request.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><b>Tasks:<\/b><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 - Setting up the project<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 - Running tests and generating a Coverage report locally<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 - Configuring GitHub Actions<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 - Setting up Codecov<\/span>\r\n<h3><b>Setting up the project<\/b><\/h3>\r\n<b>\r\n1. Create a new Unity project<\/b><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<span style=\"font-weight: 400;\">Launch the <\/span><a href=\"https:\/\/docs.unity3d.com\/Manual\/GettingStartedUnityHub.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Unity Hub<\/span><\/a><span style=\"font-weight: 400;\"> and open an existing project or create a new Unity empty 3D project. Code Coverage is available in Unity version 2019.3 and above.\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><b>2. Install the Code Coverage package\r\n<\/b>\r\n\r\n<span style=\"font-weight: 400;\">Use the <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.package-manager-ui@latest\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Unity Package Manager <\/span><\/a> <span style=\"font-weight: 400;\">(<\/span><b>Window<\/b><span style=\"font-weight: 400;\"> &gt; <\/span><b>Package Manager<\/b><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">to find and install the Code Coverage package.<\/span><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6156\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/1-InstallCoveragePackage.png\" alt=\"\" width=\"1619\" height=\"642\" \/>\r\n\r\n<span style=\"font-weight: 400;\">Alternatively, use the Add(+) dropdown and select <\/span><b><i>Add package from git URL...<\/i><\/b><span style=\"font-weight: 400;\"> or <\/span><b><i>Add package by name...<\/i><\/b><span style=\"font-weight: 400;\"> and type <\/span><code>com.unity.testtools.codecoverage<\/code><span style=\"font-weight: 400;\">.<\/span>\r\n\r\n<span style=\"font-weight: 400;\"><img class=\"alignnone size-full wp-image-6155\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/2-InstallCoveragePackage_URL.png\" alt=\"\" width=\"1622\" height=\"282\" \/><\/span>\r\n\r\n<b>3. Install the Asteroids sample project<\/b><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<span style=\"font-weight: 400;\">In the Unity Package Manager (<\/span><b>Window<\/b><span style=\"font-weight: 400;\"> &gt; <\/span><b>Package Manager<\/b><span style=\"font-weight: 400;\">) select the Code Coverage package, if not already selected.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">Find the <\/span><b>Samples <\/b><span style=\"font-weight: 400;\">section in the package details (right-hand side) and select <\/span><b>Import <\/b><span style=\"font-weight: 400;\">next to <\/span><b>Code Coverage Tutorial<\/b><span style=\"font-weight: 400;\">.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6154\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/3-ImportSample.png\" alt=\"\" width=\"1620\" height=\"698\" \/>\r\n<h3><b>Running tests and generating a Coverage report locally<\/b><span style=\"font-weight: 400;\">\r\n<\/span><\/h3>\r\n<b>\r\n1. Enable Code Coverage<\/b><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">To enable Code Coverage open the <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\/index.html?subfolder=\/manual\/CodeCoverageWindow.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Code Coverage window<\/span><\/a><span style=\"font-weight: 400;\"> (<\/span><b>Window <\/b><span style=\"font-weight: 400;\">&gt; <\/span><b>Analysis <\/b><span style=\"font-weight: 400;\">&gt; <\/span><b>Code Coverage<\/b><span style=\"font-weight: 400;\">) and select <\/span><b>Enable Code Coverage<\/b><span style=\"font-weight: 400;\"> if not already selected, to be able to generate Coverage data and reports.<\/span><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6153\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/4-EnableCodeCoverage.png\" alt=\"\" width=\"1420\" height=\"60\" \/>\r\n\r\n<b>Note:<\/b><span style=\"font-weight: 400;\"> Enabling Code Coverage adds some overhead to the editor and can affect the performance.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">If you see this warning select <\/span><b>Switch to debug mode<\/b><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6151\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/6-SwitchToDebugMode.png\" alt=\"\" width=\"1290\" height=\"165\" \/>\r\n\r\n<span style=\"font-weight: 400;\"><a href=\"https:\/\/docs.unity3d.com\/Manual\/ManagedCodeDebugging.html#CodeOptimizationMode\">Code Optimization<\/a> was introduced in Unity 2020.1; in <i>Release mode<\/i> the code is optimized and therefore not directly represented by the original code. Therefore, <i>Debug mode<\/i> is required in order to obtain accurate code coverage information.\r\n<\/span><b><\/b>\r\n\r\n<b>2. Generate a Coverage report from PlayMode tests<\/b><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<span style=\"font-weight: 400;\">1. Make sure only <\/span><code>Unity.TestTools.CodeCoverage.Sample.Asteroids<\/code><span style=\"font-weight: 400;\"> and <\/span><code>Unity.TestTools.CodeCoverage.Sample.Asteroids.Tests<\/code><span style=\"font-weight: 400;\"> assemblies are selected in <\/span><b>Included Assemblies<\/b><span style=\"font-weight: 400;\">.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">2. Make sure <\/span><b>Generate HTML Report<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Auto Generate Report<\/b><span style=\"font-weight: 400;\"> are checked.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6152\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/5-CodeCoverageWindow.png\" alt=\"\" width=\"1427\" height=\"830\" \/>\r\n\r\n<span style=\"font-weight: 400;\">3. Switch to the <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.test-framework@latest\/index.html?subfolder=\/manual\/workflow-run-test.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Test Runner<\/span><\/a><span style=\"font-weight: 400;\"> window, select the <\/span><b>PlayMode <\/b><span style=\"font-weight: 400;\">tab, and hit <\/span><b>Run All<\/b><span style=\"font-weight: 400;\"> tests.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6150\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/7-TestRunnerWindow.png\" alt=\"\" width=\"1432\" height=\"528\" \/>\r\n\r\n4. When the tests finish running, a file viewer window will open up containing the coverage report. Select <code>index.htm<\/code>.\r\n\r\n<span style=\"font-weight: 400;\">5. Look for the classes with low coverage, especially <\/span><b>LaserController<\/b><span style=\"font-weight: 400;\">, <\/span><b>BaseProjectile, <\/b><span style=\"font-weight: 400;\">and <\/span><b>ProjectileController<\/b><span style=\"font-weight: 400;\">. <\/span><span style=\"font-weight: 400;\">You can sort the results by <\/span><i><span style=\"font-weight: 400;\">Line coverage<\/span><\/i><span style=\"font-weight: 400;\">, and click on each class for a more detailed report. See <a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\/index.html?subfolder=\/manual\/HowToInterpretResults.html\" target=\"_blank\" rel=\"noopener\">How to interpret the results<\/a>.<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6149\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/8-CodeCoverageReport.png\" alt=\"\" width=\"2048\" height=\"809\" \/>\r\n\r\n&nbsp;\r\n<h3><b>Configuring GitHub Actions<\/b><span style=\"font-weight: 400;\">\r\n<\/span><\/h3>\r\n<b>\r\n1. Create a GitHub repository<\/b><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">Create a GitHub repository and push the project there. It is recommended to include GitHub\u2019s <\/span><a href=\"https:\/\/github.com\/github\/gitignore\/blob\/master\/Unity.gitignore\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">.gitignore Unity template<\/span><\/a><span style=\"font-weight: 400;\">. You can add <\/span><code>\/[Cc]ode[Cc]overage\/<\/code><span style=\"font-weight: 400;\"> in the .gitignore too.<\/span><span style=\"font-weight: 400;\">\r\n<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\r\n<\/span><b>2. Setup GitHub Actions<\/b><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">There is no officially supported way of running Unity in Github Actions, but the community has created some solutions. For this tutorial, we will use the GitHub Actions provided by <\/span><a href=\"https:\/\/game.ci\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">GameCI<\/span><\/a><span style=\"font-weight: 400;\">. <\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">1. Setting up a Unity license<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">All actions use a Unity installation, which needs to be activated. Follow the instructions on the <\/span><a href=\"https:\/\/game.ci\/docs\/github\/activation\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Activation<\/span><\/a><span style=\"font-weight: 400;\"> page in GameCI to set up a Unity license.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">2. Setting up the main workflow<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">Create a file called <\/span><code>.github\/workflows\/main.yml<\/code><span style=\"font-weight: 400;\"> and add the workflow definition below:<\/span>\r\n<pre class=\"hljs yaml\"><code>name: CI\r\n\r\non: \r\n # Replace with your main branch if needed\r\n push:\r\n branches:\r\n - main\r\n pull_request: \r\n branches:\r\n - main\r\n\r\njobs:\r\n\r\n runTests:\r\n\r\n name: Run Tests\r\n runs-on: ubuntu-latest\r\n\r\n steps:\r\n\r\n - name: Checkout repository\r\n uses: actions\/checkout@v2\r\n with:\r\n lfs: true\r\n\r\n - name: Cache Library\r\n uses: actions\/cache@v2\r\n with:\r\n path: Library\r\n key: Library\r\n\r\n - name: Run tests and generate Coverage XML report\r\n uses: game-ci\/unity-test-runner@v2\r\n env:\r\n UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}\r\n with:\r\n\t # Replace with the Unity version your project should be tested on.\r\n<span style=\"font-weight: 400;\"> # Minimum version: 2019.3<\/span>\r\n unityVersion: 2020.3.13f1\r\n testMode: playmode\r\n customParameters: -debugCodeOptimization -enableCodeCoverage -coverageResultsPath .\/coverage-results -coverageOptions generateAdditionalMetrics\r\n<\/code><\/pre>\r\n<span style=\"font-weight: 400;\">This workflow triggers when you push code to the <\/span><code>main<\/code><span style=\"font-weight: 400;\"> branch in the repository, or create\/update a pull request. It contains a <\/span><code>runTests<\/code><span style=\"font-weight: 400;\"> job which has 3 steps:<\/span>\r\n<ul>\r\n \t<li><span style=\"font-weight: 400;\">Check out the repository<\/span><\/li>\r\n \t<li><span style=\"font-weight: 400;\">Cache the Library folder<\/span><\/li>\r\n \t<li><span style=\"font-weight: 400;\">Run the PlayMode tests and generate a Coverage XML report.<\/span><\/li>\r\n<\/ul>\r\n<b>Note:<\/b><span style=\"font-weight: 400;\"> The code coverage arguments are passed in <\/span><code>customParameters<\/code><span style=\"font-weight: 400;\">. See <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\/index.html?subfolder=\/manual\/CoverageBatchmode.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Using Code Coverage in batchmode<\/span><\/a><span style=\"font-weight: 400;\"> for more information.\u00a0 <\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">Commit and push your workflow definition.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">Go to the Actions tab in GitHub and select the latest commit\u2019s workflow.\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\"><img class=\"alignnone size-full wp-image-6148\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/9-MainAction.png\" alt=\"\" width=\"1927\" height=\"913\" \/><\/span>\r\n<h3><\/h3>\r\n<h3><b>Setting up Codecov<\/b><\/h3>\r\n&nbsp;\r\n\r\n<b>1. Sign Up to Codecov<\/b><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">If you don\u2019t already have an account, head over to <\/span><a href=\"https:\/\/about.codecov.io\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codecov<\/span><\/a><span style=\"font-weight: 400;\"> and sign up with your GitHub account. Once you do that, you\u2019ll see a list of your GitHub repositories. Choose the repository you just created to link it with Codecov. You will be presented with an upload token. If your repository is private, you need to copy the upload token from the Codecov dashboard and paste it into a <\/span><a href=\"https:\/\/docs.github.com\/en\/actions\/reference\/encrypted-secrets\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">GitHub encrypted secret<\/span><\/a><span style=\"font-weight: 400;\"> named <\/span><code>CODECOV_TOKEN.<\/code>\r\n\r\n<b>2. Setup Codecov GitHub Action<\/b>\r\n\r\n<span style=\"font-weight: 400;\">We are now going to add a new step in the workflow, which will upload the Coverage XML report to Codecov: <\/span>\r\n<pre class=\"hljs yaml\"><code> - name: Upload XML report to Codecov\r\n uses: codecov\/codecov-action@v2\r\n with:\r\n name: PlayMode\r\n flags: automated\r\n token: ${{ secrets.CODECOV_TOKEN }}\r\n files: coverage-results\/**\/*.xml\r\n<\/code><\/pre>\r\n<span style=\"font-weight: 400;\">Commit and push the updated workflow definition.<\/span>\r\n\r\n<span style=\"font-weight: 400;\"><b>3. View Codecov report<\/b><\/span>\r\n\r\nWhen the new workflow finishes, navigate to the repository in the <a href=\"https:\/\/codecov.io\/gh\" target=\"_blank\" rel=\"noopener\">Codecov dashboard<\/a>\u00a0and select the latest commit.\r\n\r\n<img class=\"alignnone size-full wp-image-6147\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/10-CodecovReport.png\" alt=\"\" width=\"1927\" height=\"751\" \/>\r\n\r\n<b>4. Integrating with Pull Requests<\/b><b>\r\n<\/b>\r\n\r\n1. Grant access to the <a href=\"https:\/\/github.com\/marketplace\/codecov\" target=\"_blank\" rel=\"noopener\">Codecov bot<\/a> to your account.<b>\r\n<\/b>\r\n\r\n<span style=\"font-weight: 400;\">2. Create a new branch and name it <\/span><code>add-weapon-tests<span style=\"font-weight: 400;\">.\r\n<\/span><\/code>\r\n\r\n<span style=\"font-weight: 400;\">3. Add Weapon tests to improve coverage; open the <\/span><code>Tests\/WeaponTests.cs<\/code><span style=\"font-weight: 400;\"> script and uncomment all the tests (from line 35 down to line 237).<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">4. Commit and push the changes.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">5. Create a pull request from the new branch. You should see a report like the one below on the pull request when the actions complete:<\/span>\r\n\r\n<img class=\"alignnone size-full wp-image-6146\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/09\/11-CodecovPRReport.png\" alt=\"\" width=\"1538\" height=\"1427\" \/>\r\n\r\n<span style=\"font-weight: 400;\">Observe that the coverage increases as expected.<\/span><span style=\"font-weight: 400;\">\r\n<\/span><span style=\"font-weight: 400;\">\r\n<\/span><b>Note:<\/b><span style=\"font-weight: 400;\"> To configure the Codecov Report shown in the pull request, you can add a codecov.yml file in the root of the project, or update the Codecov Yaml file in the Codecov dashboard. See <\/span><a href=\"https:\/\/docs.codecov.com\/docs\/codecov-yaml\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">About Codecov yaml<\/span><\/a><span style=\"font-weight: 400;\"> for more information.<\/span><span style=\"font-weight: 400;\">\r\n<\/span>\r\n<h3>Conclusion<\/h3>\r\n<span style=\"font-weight: 400;\">In this tutorial, you learned about how code coverage is important for identifying portions of your code that are not covered by automated tests. Code coverage lets you understand where your tests are lacking and helps you detect bugs early.<\/span>\r\n\r\n<span style=\"font-weight: 400;\">You also learned how to set up code coverage in a Unity project using the <\/span><a href=\"https:\/\/docs.unity3d.com\/Packages\/com.unity.testtools.codecoverage@latest\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Code Coverage package<\/span><\/a><span style=\"font-weight: 400;\"> and how to integrate <\/span><a href=\"https:\/\/about.codecov.io\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Codecov<\/span><\/a><span style=\"font-weight: 400;\"> with your GitHub repository using <\/span><a href=\"https:\/\/github.com\/features\/actions\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">GitHub Actions<\/span><\/a><span style=\"font-weight: 400;\"> to generate coverage reports every time you push changes or make a pull request.<\/span>","post_title":"How to Set Up Codecov with Unity and GitHub Actions","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"how-to-set-up-codecov-with-unity-and-github-actions","to_ping":"","pinged":"","post_modified":"2023-01-25 12:08:11","post_modified_gmt":"2023-01-25 17:08:11","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=6001","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":false,"tools":[241,230],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/09092021_How-to-Set-Up-Codecov-with-Unity-and-GitHub-Actions-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/09092021_How-to-Set-Up-Codecov-with-Unity-and-GitHub-Actions-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/how-to-set-up-codecov-with-unity-and-github-actions\/","authorID":"59","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/07\/1545051178061-removebg-preview.png","authorDisplayName":"Nikos Chagialas","authorURL":"https:\/\/www.linkedin.com\/in\/nikosc\/","cta":"Read Blog Post"},{"ID":5325,"post_author":"38","post_date":"2021-06-17 15:06:31","post_date_gmt":"2021-06-17 19:06:31","post_content":"When you\u2019re working on a long, or ongoing project, quality can start to slip as your codebase gets more and more complex. One of the best ways to ensure your code quality stays high over time is to monitor your test coverage, also known as code coverage.\r\n\r\nCode coverage is the measure of how much code is executed during testing. Simply put, it's the percentage of lines of code that have a test that executes against it. A program with high code coverage has been thoroughly tested and has a lower chance of containing software bugs.\r\n\r\n<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>, a code coverage tool available for GitHub, GitLab, and Bitbucket. We calculate the coverage ratio by examining which lines of code were executed while running the unit tests. Codecov is language agnostic and dedicated to working in a developer\u2019s workflow without disruptions or without adding complexities to the already existing ecosystem.\r\n\r\nIt\u2019s the perfect tool for code coverage in a Scala environment, and in this article, we\u2019ll teach you how to set it up and generate coverage reports every time changes are pushed using GitHub Actions and Codecov.\r\n<h2 id=\"step-1-running-tests-locally\">Step 1: Running Tests Locally<\/h2>\r\nAs a software engineer, you have probably learned over time that just because your code compiles does not mean that it's correct and does all it's meant to do. That is why you write unit tests.\r\n\r\nYou will start by writing unit tests for a simple Scala program that prints \"Hello world,\" and another that does a simple arithmetic addition.\r\n\r\nCreate a new package in the directory\u00a0<code>src\/test\/scala<\/code>\u00a0and call it\u00a0<code>org.example<\/code>. Under the package, create a Scala class named\u00a0<code>GreetingsTest<\/code>\u00a0where you will add the unit tests for your\u00a0<code>Greetings.scala<\/code>\u00a0class. Add the following code snippet:\r\n<pre><code><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">GreetingsTest<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">AnyFlatSpecLike<\/span> <span class=\"hljs-keyword\">with<\/span> <span class=\"hljs-title\">Matchers<\/span> <\/span>{\r\n\r\n behavior.of(<span class=\"hljs-string\">\"greetings class\"<\/span>)\r\n\r\n it should <span class=\"hljs-string\">\"print greetings\"<\/span> in {\r\n <span class=\"hljs-type\">Greetings<\/span>.printGreeting() shouldEqual <span class=\"hljs-string\">\"Hello world!\"<\/span>\r\n }\r\n\r\n it should <span class=\"hljs-string\">\"compute addition\"<\/span> in {\r\n <span class=\"hljs-type\">Greetings<\/span>.addSomeNumbers() shouldEqual <span class=\"hljs-number\">12<\/span>\r\n }\r\n\r\n}\r\n<\/code><\/pre>\r\nCreate a new package in the directory\u00a0<code>src\/main\/scala<\/code>\u00a0and call it\u00a0<code>org.example<\/code>, like you did for the unit tests above. Under the package, create a Scala object named\u00a0<code>Greetings<\/code>\u00a0where you will write your\u00a0<code>Greetings.scala<\/code>\u00a0class. Add the code snippet below:\r\n<pre><code><span class=\"hljs-class\"><span class=\"hljs-keyword\">object<\/span> <span class=\"hljs-title\">Greetings<\/span> <\/span>{\r\n\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">main<\/span><\/span>(args: <span class=\"hljs-type\">Array<\/span>[<span class=\"hljs-type\">String<\/span>]): <span class=\"hljs-type\">Unit<\/span> = {\r\n <span class=\"hljs-keyword\">val<\/span> greetings = printGreeting()\r\n <span class=\"hljs-keyword\">val<\/span> addition = addSomeNumbers()\r\n\r\n println(greetings + <span class=\"hljs-string\">\" The addition is \"<\/span> + addition)\r\n }\r\n\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">printGreeting<\/span><\/span>(): <span class=\"hljs-type\">String<\/span> =\r\n <span class=\"hljs-string\">\"Hello world!\"<\/span>\r\n\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">addSomeNumbers<\/span><\/span>(): <span class=\"hljs-type\">Int<\/span> =\r\n <span class=\"hljs-number\">6<\/span> + <span class=\"hljs-number\">6<\/span>\r\n\r\n}\r\n<\/code><\/pre>\r\nBefore you run your unit tests, you will need to set up library dependencies for the tests to be executed. In your\u00a0<code>build.sbt<\/code>\u00a0file, add the code snippet below that will add dependencies for your unit tests:\r\n<pre><code><span class=\"hljs-string\">name :<\/span>= <span class=\"hljs-string\">\"CodecovScala\"<\/span>\r\n<span class=\"hljs-keyword\">import<\/span> com.typesafe.sbt.SbtNativePackager.Universal\r\n<span class=\"hljs-string\">scalaVersion :<\/span>= <span class=\"hljs-string\">\"2.13.1\"<\/span>\r\n<span class=\"hljs-string\">version :<\/span>= <span class=\"hljs-string\">\"1.0\"<\/span>\r\n\r\nlibraryDependencies += <span class=\"hljs-string\">\"org.seleniumhq.selenium\"<\/span> % <span class=\"hljs-string\">\"selenium-java\"<\/span> % <span class=\"hljs-string\">\"3.141.59\"<\/span>\r\nlibraryDependencies += <span class=\"hljs-string\">\"commons-io\"<\/span> % <span class=\"hljs-string\">\"commons-io\"<\/span> % <span class=\"hljs-string\">\"2.8.0\"<\/span>\r\nlibraryDependencies += <span class=\"hljs-string\">\"org.scala-lang.modules\"<\/span> %% <span class=\"hljs-string\">\"scala-parser-combinators\"<\/span> % <span class=\"hljs-string\">\"1.1.2\"<\/span>\r\nlibraryDependencies += <span class=\"hljs-string\">\"org.scalatest\"<\/span> %% <span class=\"hljs-string\">\"scalatest\"<\/span> % <span class=\"hljs-string\">\"3.2.8\"<\/span> % Test\r\nlibraryDependencies += <span class=\"hljs-string\">\"org.scalamock\"<\/span> %% <span class=\"hljs-string\">\"scalamock\"<\/span> % <span class=\"hljs-string\">\"5.1.0\"<\/span> % Test\r\n\r\nenablePlugins(JavaAppPackaging)\r\n\r\nmappings <span class=\"hljs-keyword\">in<\/span> Universal += {\r\n file(<span class=\"hljs-string\">\"resources\/chromedriver\"<\/span>) -&gt; <span class=\"hljs-string\">\"resources\/chromedriver\"<\/span>\r\n}\r\n<\/code><\/pre>\r\n<code>name<\/code>\u00a0here is your project name\u2014you could call it anything. Make sure you use the current stable version of Scala to avoid issues when running your program.\r\n\r\nIn your command line, run the command\u00a0<code>sbt clean test<\/code>\u00a0to test your setup.\r\n<pre><code>sbt clean <span class=\"hljs-built_in\">test<\/span>\r\n<\/code><\/pre>\r\nYou should be able to see the coveted green checkmarks that mean your tests just passed.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/c9qmfzg.png\" alt=\"tests-pass.png\" \/>\r\n\r\nGreat! You have accomplished your first task. Now let's head over to\u00a0<a href=\"https:\/\/github.com\/\">GitHub<\/a>\u00a0and set up your GitHub Actions workflow.\r\n<h2 id=\"step-2-configuring-github-actions\">Step 2: Configuring GitHub Actions<\/h2>\r\nIn today's fast-paced environment, it's absolutely essential to automate code testing and delivery. That's where\u00a0<a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a>\u00a0come in. GitHub Actions ensures that after tests are passed, delivery of your code is automated, thus reducing the time it takes you to deliver updates to your application, and in the long run allows you to focus on the code itself.\r\n\r\nTo set up GitHub Actions for your\u00a0<code>Greetings.scala<\/code>\u00a0project, head over to GitHub and create a repository for it.\r\n\r\nClick the\u00a0<strong>Actions<\/strong>\u00a0tab at the top of your repository. You will notice a huge list of workflow templates. This means that you don't need to write your workflows from scratch.\r\n\r\nFor this tutorial, select the Scala workflow.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/NX74F8a.png\" alt=\"choose-workflow.png\" \/>\r\n\r\nGitHub Actions will run your workflow build automatically. If all went well, you should see a successful clean build.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/HYDU9dL.png\" alt=\"workflow-build.png\" \/>\r\n\r\nAs you can see, your\u00a0<code>Greetings.scala<\/code>\u00a0class has been tested and passed. Sometimes you will want this result displayed on your repository whenever commits are pushed. You can achieve that by creating a badge in your README.md. To do that, click the three-dotted settings icon to reveal a drop-down menu. Select\u00a0<strong>Create status badge<\/strong>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/l9Xs40u.png\" alt=\"create-badge.png\" \/>\r\n\r\nCopy the Markdown text in the box and paste it inside your README.md. You should be able to see your badge emblazoned with passing text inside it.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/AKWAxPn.png\" alt=\"workflow-badge.png\" \/>\r\n\r\nLooks great, huh? Look what you\u2019ve achieved already! You\u2019ve written unit tests for your Scala project and used GitHub Actions to automate your delivery work.\r\n<h2 id=\"step-3-setting-up-codecov-for-code-coverage-reporting\">Step 3: Setting Up Codecov for Code Coverage Reporting<\/h2>\r\nYou may recognize that in\u00a0<strong>TDD<\/strong>\u00a0(Test Driven Development), your low-level design is improved, as well as giving you confidence when writing code. The result of great unit tests is when you have efficient code coverage.\r\n\r\nTo set up Codecov for code coverage in your project, head over to the\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov website<\/a>\u00a0and register using your GitHub account. Then, select your repository.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/MxcCWDf.png\" alt=\"choose-repo.png\" \/>\r\n\r\nThat's it! Now you need to set up your project to be able to send coverage reports to Codecov. To do that, head over to your IDE and add a few code snippets.\r\n\r\nIn your project directory, create a file named\u00a0<code>plugins.sbt<\/code>\u00a0and add the following dependencies.\r\n<pre><code><span class=\"hljs-function\"><span class=\"hljs-title\">addSbtPlugin<\/span><span class=\"hljs-params\">(<span class=\"hljs-string\">\"org.scoverage\"<\/span> % <span class=\"hljs-string\">\"sbt-scoverage\"<\/span> % <span class=\"hljs-string\">\"1.7.2\"<\/span>)<\/span><\/span>\r\n<span class=\"hljs-function\"><span class=\"hljs-title\">addSbtPlugin<\/span><span class=\"hljs-params\">(<span class=\"hljs-string\">\"org.scalameta\"<\/span> % <span class=\"hljs-string\">\"sbt-scalafmt\"<\/span> % <span class=\"hljs-string\">\"2.4.2\"<\/span>)<\/span><\/span>\r\n<span class=\"hljs-function\"><span class=\"hljs-title\">addSbtPlugin<\/span><span class=\"hljs-params\">(<span class=\"hljs-string\">\"com.typesafe.sbt\"<\/span> % <span class=\"hljs-string\">\"sbt-native-packager\"<\/span> % <span class=\"hljs-string\">\"1.8.1\"<\/span>)<\/span><\/span>\r\n<\/code><\/pre>\r\nRun the command below to run tests with coverage:\r\n<pre><code><span class=\"hljs-attribute\">sbt coverageReport<\/span>\r\n<\/code><\/pre>\r\nYou should see coverage reports printed next to your\u00a0<code>Greetings.class<\/code>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/VBU4Sp3.png\" alt=\"coverage-result.png\" \/>\r\n\r\nFrom the above report, you can see that your report metrics are not 100 percent because the print statements have not been covered by your test coverage. This gives you valuable insights about your code and what actions to proceed with and if they are important to test or not. In this case, there is almost zero need to test print statements.\r\n\r\nIn your root project directory, when you created the GitHub Actions workflow, a file was created under directory\u00a0<code>.github\/workflows\/scala.yml<\/code>. You will need to add a few code snippets to the\u00a0<code>scala.yml<\/code>\u00a0file to upload these test coverage results to Codecov.\r\n\r\nIn your\u00a0<code>scala.yml<\/code>\u00a0file, add the workflow snippet below:\r\n<pre><code><span class=\"hljs-attribute\">name<\/span>: Scala CI\r\n\r\n<span class=\"less\"><span class=\"hljs-attribute\">on<\/span>:\r\n <span class=\"hljs-attribute\">push<\/span>:\r\n <span class=\"hljs-attribute\">branches<\/span>:\r\n - main\r\n - development\r\n <span class=\"hljs-attribute\">pull_request<\/span>:\r\n <span class=\"hljs-attribute\">branches<\/span>:\r\n - main\r\n - development\r\n\r\n<span class=\"hljs-attribute\">jobs<\/span>:\r\n <span class=\"hljs-attribute\">build<\/span>:\r\n <span class=\"hljs-attribute\">runs-on<\/span>: ubuntu-latest\r\n <span class=\"hljs-attribute\">steps<\/span>:\r\n - <span class=\"hljs-attribute\">uses<\/span>: actions\/checkout<span class=\"hljs-variable\">@v2<\/span>\r\n - <span class=\"hljs-attribute\">name<\/span>: Run tests\r\n <span class=\"hljs-attribute\">run<\/span>: sbt coverage test\r\n - <span class=\"hljs-attribute\">name<\/span>: Coverage Report\r\n <span class=\"hljs-attribute\">run<\/span>: sbt coverageReport\r\n - <span class=\"hljs-attribute\">name<\/span>: <span class=\"hljs-string\">\"Upload coverage to Codecov\"<\/span>\r\n <span class=\"hljs-attribute\">uses<\/span>: <span class=\"hljs-string\">\"codecov\/codecov-action@v2\"<\/span>\r\n <span class=\"hljs-attribute\">with<\/span>:\r\n <span class=\"hljs-attribute\">fail_ci_if_error<\/span>: true<\/span>\r\n<\/code><\/pre>\r\nHere, you are defining a job called\u00a0<em>build<\/em>\u00a0that is going to run unit tests and generate a coverage report.\r\n\r\nIn the build job, we define three steps:\r\n<ol>\r\n \t<li>One to run the test with coverage<\/li>\r\n \t<li>One to generate the coverage report<\/li>\r\n \t<li>One to upload the coverage to Codecov<\/li>\r\n<\/ol>\r\nTo test the whole workflow, push a new branch with the\u00a0<code>scala.yml<\/code>\u00a0file and create a new pull request targeting the development branch. Once the PR is open, the workflow will start. A successful build will result in the image below in your GitHub Actions.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/3p50WBD.png\" alt=\"git-workflow-codecov-report.png\" \/>\r\n\r\nThe code coverage report will be uploaded to Codecov and represented by a badge as a percentage to give you valuable insights on how much code was covered during tests.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/rcrL1xh.png\" alt=\"codecov-badge.png\" \/>\r\n\r\nYour code coverage reports should aim at scores above 80 percent to be considered satisfactory. In a real-life production application, that\u2019s an important metric to consider.\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nCongratulations! You learned how to set up code coverage in a Scala application and generate code coverage reports every time changes are pushed using GitHub Actions, uploading the reports to Codecov. You also learned how to write unit tests for your Scala application and set up the whole workflow for continuous delivery.\r\n\r\nYou\u2019ve just scratched the surface of code coverage, and there is much more to learn, both about the concept and the\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>\u00a0tool.","post_title":"How to Set Up Codecov with Scala and GitHub Actions","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"how-to-set-up-codecov-with-scala-and-github-actions","to_ping":"","pinged":"","post_modified":"2023-01-24 11:38:18","post_modified_gmt":"2023-01-24 16:38:18","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=5325","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[42],"tools":[230,241],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/06172021_How-to-Set-Up-Codecov-with-Scala-and-GitHub-Actions-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/06172021_How-to-Set-Up-Codecov-with-Scala-and-GitHub-Actions-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/how-to-set-up-codecov-with-scala-and-github-actions\/","authorID":"38","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/04\/derrick-removebg-preview.png","authorDisplayName":"Derrick Wadek","authorURL":"https:\/\/www.linkedin.com\/in\/derrick-wadek-166a889b\/","cta":"Read Blog Post"},{"ID":5236,"post_author":"56","post_date":"2021-06-10 11:25:14","post_date_gmt":"2021-06-10 15:25:14","post_content":"Tests are an important component of software development: they help prevent bugs and can act as documentation. One of the best ways to ensure your code quality stays high over time is to monitor your test coverage, through a measure known as code coverage. Monitoring code coverage is essential to maintaining code quality, and there are many tools out there that can assist with this.\r\n\r\n<a href=\"https:\/\/github.com\/OpenCppCoverage\/OpenCppCoverage\">OpenCppCoverage<\/a>\u00a0is an open-source C++ code coverage tool for Windows that can generate coverage reports locally, and then leverage Codecov GitHub Actions to integrate coverage reports in your CI pipeline.\r\n\r\nIn this tutorial, you will learn the basics of OpenCppCoverage and how to integrate it into your CI pipeline. If you\u2019d like to skip ahead to the full code for the demo, it is available\u00a0<a href=\"https:\/\/github.com\/imaculate\/HelloCovDemo\">here<\/a>.\r\n<h2 id=\"running-tests-and-coverage-locally\">Running Tests and Coverage Locally<\/h2>\r\nTo follow this tutorial, you need Windows Vista or higher and Microsoft Visual Studio 2008 or higher. You can clone the demo repository with the following command:\r\n<pre><code class=\"lang-Git\">git <span class=\"hljs-keyword\">clone<\/span> <span class=\"hljs-title\">https<\/span>:\/\/github.com\/imaculate\/HelloCovDemo.git\r\n<\/code><\/pre>\r\nAlternatively, you can proceed with the step-by-step instructions below.\r\n<h3 id=\"1-creating-a-library\">1. Creating a Library<\/h3>\r\nFirst, you will create a static library project from Visual Studio. The library will house computations below that can be performed with bit operations.\r\n<pre><code class=\"lang-C++\"><span class=\"hljs-comment\">\/\/ HelloCov.h<\/span>\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">is_power_of_two<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> n)<\/span><\/span>;\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">multiply_by_two<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> n)<\/span><\/span>;\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">divide_by_two<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> n)<\/span><\/span>;\r\n<\/code><\/pre>\r\n<pre><code class=\"lang-C++\"><span class=\"hljs-comment\">\/\/HelloCov.cpp<\/span>\r\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"HelloCov.h\"<\/span><\/span>\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">is_power_of_two<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> n)<\/span>\r\n<\/span>{\r\n <span class=\"hljs-keyword\">if<\/span> (n &lt; <span class=\"hljs-number\">0<\/span>)\r\n <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\r\n\r\n <span class=\"hljs-keyword\">return<\/span> (n &amp; (n - <span class=\"hljs-number\">1<\/span>)) == <span class=\"hljs-number\">0<\/span>;\r\n}\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">multiply_by_two<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> n)<\/span>\r\n<\/span>{\r\n <span class=\"hljs-keyword\">return<\/span> n &lt;&lt; <span class=\"hljs-number\">1<\/span>;\r\n}\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">divide_by_two<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> n)<\/span>\r\n<\/span>{\r\n <span class=\"hljs-keyword\">return<\/span> n &gt;&gt; <span class=\"hljs-number\">1<\/span>;\r\n}\r\n<\/code><\/pre>\r\nEnsure the library compiles successfully, then proceed to add tests.\r\n<h3 id=\"2-add-tests\">2. Add Tests<\/h3>\r\nIn the same solution, add a\u00a0<code>Native Unit Test Project<\/code>\u00a0with reference to the\u00a0<code>HelloCov<\/code>\u00a0library. In a source file, add one test method for each function as follows:\r\n<pre><code class=\"lang-C++\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"CppUnitTest.h\"<\/span><\/span>\r\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"..\/HelloCov\/HelloCov.h\"<\/span><\/span>\r\n\r\n<span class=\"hljs-keyword\">using<\/span> <span class=\"hljs-keyword\">namespace<\/span> Microsoft::VisualStudio::CppUnitTestFramework;\r\n\r\n<span class=\"hljs-keyword\">namespace<\/span> HelloCovTest\r\n{\r\n TEST_CLASS(Test1)\r\n {\r\n <span class=\"hljs-keyword\">public<\/span>:\r\n\r\n TEST_METHOD(IsPowerOfTwo)\r\n {\r\n Assert::IsTrue(is_power_of_two(<span class=\"hljs-number\">8<\/span>));\r\n }\r\n\r\n TEST_METHOD(MultiplyByTwo)\r\n {\r\n Assert::AreEqual(<span class=\"hljs-number\">14<\/span>, multiply_by_two(<span class=\"hljs-number\">7<\/span>));\r\n }\r\n\r\n TEST_METHOD(DivideByTwo)\r\n {\r\n Assert::AreEqual(<span class=\"hljs-number\">-4<\/span>, divide_by_two(<span class=\"hljs-number\">-7<\/span>));\r\n }\r\n };\r\n}\r\n<\/code><\/pre>\r\nVerify that all the tests pass.\r\n<h3 id=\"3-install-opencppcoverage\">3. Install OpenCppCoverage<\/h3>\r\nThere are two ways to install it\u2014using\u00a0<a href=\"https:\/\/chocolatey.org\/\">Chocolatey<\/a>:\r\n<pre><code class=\"lang-cmd\">choco <span class=\"hljs-keyword\">install<\/span> opencppcoverage\r\n<\/code><\/pre>\r\nOr using the interactive installer. Go to\u00a0<a href=\"https:\/\/github.com\/OpenCppCoverage\/OpenCppCoverage\/releases\">releases<\/a>\u00a0and download the latest release of the installer.\r\n<h3 id=\"4-generate-code-coverage-report\">4. Generate Code Coverage Report<\/h3>\r\nFrom the root directory of the solution, run the following command:\r\n<pre><code class=\"lang-cmd\">OpenCppCoverage --sources HelloCov -- \"C:<span class=\"hljs-symbol\">\\P<\/span>rogram Files (x86)<span class=\"hljs-symbol\">\\M<\/span>icrosoft Visual Studio<span class=\"hljs-symbol\">\\2<\/span>019<span class=\"hljs-symbol\">\\C<\/span>ommunity<span class=\"hljs-symbol\">\\C<\/span>ommon7<span class=\"hljs-symbol\">\\I<\/span>DE<span class=\"hljs-symbol\">\\C<\/span>ommonExtensions<span class=\"hljs-symbol\">\\M<\/span>icrosoft<span class=\"hljs-symbol\">\\T<\/span>estWindow<span class=\"hljs-symbol\">\\v<\/span>stest.console.exe\" debug\/HelloTest.dll\r\n<\/code><\/pre>\r\nThe path of\u00a0<code>vstest.console.exe<\/code>\u00a0depends on your version of Visual Studio, so update it accordingly. The report will be generated in the folder\u00a0<code>CodeCoverage-&lt;Timestamp&gt;<\/code>. You can view it by opening\u00a0<code>index.html<\/code>\u00a0in a browser. On navigating to the report for\u00a0<code>HelloTest.dll<\/code>\u00a0&gt;\u00a0<code>HelloCov.cpp<\/code>, you will see the line coverage like below:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/qaeNYKL.png\" alt=\"Capture of line coverage\" \/>\r\n<h2 id=\"configuring-github-actions\">Configuring GitHub Actions<\/h2>\r\nCoverage reports are most useful when making changes to your code. In this section, you will integrate Codecov into your workflow so that you are able to view reports on pull requests or pushes to your repo.\r\n<h3 id=\"1-repo\">1. Repo<\/h3>\r\nCreate a public GitHub and push to it the solution above.\r\n<h3 id=\"2-sign-up-for-codecov\">2. Sign Up for Codecov<\/h3>\r\nIf you don't already have an account, head over to\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>\u00a0and sign up with your GitHub account. Select the repo you will be integrating. This tutorial uses a public repo for simplicity but if your repo is private you will be provided a token. Alternatively, you can add a repo by navigating to\u00a0<code>https:\/\/app.codecov.io\/gh\/&lt;gh-username&gt;\/&lt;repo-name&gt;<\/code>.\r\n<h3 id=\"3-setup-github-actions\">3. Setup GitHub Actions<\/h3>\r\n<a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a>\u00a0make it easy to automate software workflows. You'll set up a workflow to essentially run OpenCppCoverage on a Windows machine, then upload the report to CodeCov. These actions are specified in a YAML file in the\u00a0<code>.github\/workflows<\/code>\u00a0directory in your repo. Add the YAML file below to your workflows folder:\r\n<pre><code class=\"lang-yml\"><span class=\"hljs-attr\">name:<\/span> Upload CodeCov Report\r\n<span class=\"hljs-attr\">on:<\/span> [push, pull_request]\r\n<span class=\"hljs-attr\">jobs:<\/span>\r\n<span class=\"hljs-attr\"> run:<\/span>\r\n<span class=\"hljs-attr\"> runs-on:<\/span> windows-latest\r\n<span class=\"hljs-attr\"> name:<\/span> Build, Test , Upload Code Coverage Report\r\n<span class=\"hljs-attr\"> steps:<\/span>\r\n<span class=\"hljs-attr\"> - name:<\/span> Checkout code\r\n<span class=\"hljs-attr\"> uses:<\/span> actions\/checkout@v2\r\n<span class=\"hljs-attr\"> with:<\/span>\r\n<span class=\"hljs-attr\"> fetch-depth:<\/span> \u2018<span class=\"hljs-number\">2<\/span>\u2019\r\n<span class=\"hljs-attr\"> id:<\/span> checkout_code\r\n<span class=\"hljs-attr\"> - name:<\/span> Setup MSBuild and add to PATH\r\n<span class=\"hljs-attr\"> uses:<\/span> microsoft\/setup-msbuild@v1<span class=\"hljs-number\">.0<\/span><span class=\"hljs-number\">.2<\/span>\r\n<span class=\"hljs-attr\"> id:<\/span> setup_msbuild\r\n<span class=\"hljs-attr\"> - name:<\/span> Run MSBuild\r\n<span class=\"hljs-attr\"> id:<\/span> run_msbuild\r\n<span class=\"hljs-attr\"> run:<\/span> msbuild \/p:Configuration=Debug \/p:Platform=x86 HelloCovDemo.sln\r\n<span class=\"hljs-attr\"> - name:<\/span> Setup VSTest and add to PATH\r\n<span class=\"hljs-attr\"> uses:<\/span> darenm\/Setup-VSTest@v1\r\n<span class=\"hljs-attr\"> id:<\/span> setup_vstest\r\n<span class=\"hljs-attr\"> - name:<\/span> Setup OpenCppCoverage and add to PATh\r\n<span class=\"hljs-attr\"> id:<\/span> setup_opencppcoverage\r\n<span class=\"hljs-attr\"> run:<\/span> <span class=\"hljs-string\">|\r\n choco install OpenCppCoverage -y\r\n echo \"C:\\Program Files\\OpenCppCoverage\" &gt;&gt; $env:GITHUB_PATH\r\n<\/span><span class=\"hljs-attr\"> - name:<\/span> Generate Report\r\n<span class=\"hljs-attr\"> id:<\/span> generate_test_report\r\n<span class=\"hljs-attr\"> shell:<\/span> cmd\r\n<span class=\"hljs-attr\"> run:<\/span> OpenCppCoverage.exe --sources HelloCov --export_type cobertura:HelloCov.xml -- <span class=\"hljs-string\">\"vstest.console.exe\"<\/span> Debug\\HelloTest.dll\r\n<span class=\"hljs-attr\"> - name:<\/span> Upload Report to Codecov\r\n<span class=\"hljs-attr\"> uses:<\/span> codecov\/codecov-action@v2\r\n<span class=\"hljs-attr\"> with:<\/span>\r\n<span class=\"hljs-attr\"> files:<\/span> .\/HelloCov.xml\r\n<span class=\"hljs-attr\"> fail_ci_if_error:<\/span> <span class=\"hljs-literal\">true<\/span>\r\n<span class=\"hljs-attr\"> functionalities:<\/span> fix\r\n<\/code><\/pre>\r\nThe actions are described by their respective\u00a0<code>name<\/code>\u00a0properties. They mirror what we manually did to generate local reports i.e setup, build, test,k and coverage. Of importance are the last two actions that generate and upload the report. The\u00a0<code>OpenCppCoverage<\/code>\u00a0command is similar to the one used locally, and the\u00a0<code>export_type<\/code>\u00a0parameter is added to get the report in xml, one of the Codecov supported formats. The absolute path of vstest is not required since\u00a0<code>setup_vstest<\/code>\u00a0action added it to global PATH. When you push this change you can monitor the workflow from the Actions tab of the repo on GitHub.\r\n<h3 id=\"4-view-codecov-report\">4. View Codecov Report<\/h3>\r\nIf the workflow succeeds, at the end of logs for the upload action, there will be a link to the Codecov report like below:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/D2NdzXo.png\" alt=\"report\" \/>\r\n\r\nNavigate to the link for a detailed report including the conspicuous coverage percentage. Under the Files tab, you can view line-by-line coverage for each file.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/z1Yi7ZE.png\" alt=\"linecoverage\" \/>\r\n\r\nUnder the Graphs tab, you can view graphical representations of your coverage, like the sunburst below:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/LcSojru.png\" alt=\"Sunburst\" \/>\r\n\r\n<a href=\"https:\/\/docs.codecov.io\/docs\/graphs#sunburst\">Sunburst graphs<\/a>\u00a0enable you to navigate into project folders in order to discover files that lack coverage. The size of each slice is proportional to the number of coverage lines and the color indicates coverage. Click on a block to enter a folder and click the innermost circle to leave it.\r\n<h3 id=\"5-change-report\">5. Change Report<\/h3>\r\nTo view coverage reports as comments on pull requests, set up as follows:\r\n<ul>\r\n \t<li>Add empty\u00a0<code>codecov.yml<\/code>\u00a0to the root of the repo.<\/li>\r\n \t<li>Grant access to the\u00a0<a href=\"https:\/\/github.com\/marketplace\/codecov\">codecov bot<\/a>\u00a0to your account.To verify the setup, on a separate branch, write tests to cover the lines that have not been covered:<\/li>\r\n<\/ul>\r\n<pre><code class=\"lang-C++\"><span class=\"hljs-selector-tag\">TEST_METHOD<\/span>(<span class=\"hljs-selector-tag\">IsNegativePowerOfTwo<\/span>)\r\n{\r\n <span class=\"hljs-attribute\">Assert<\/span>::<span class=\"hljs-built_in\">IsFalse<\/span>(is_power_of_two(-8));\r\n}\r\n<\/code><\/pre>\r\nPush and create a pull request from the branch. You should see a report like below on the pull request when the actions complete:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/wQh4cVS.png\" alt=\"PR comment\" \/>\r\n\r\nObserve that coverage increases as expected.\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nCode coverage is vital to ensuring that your software quality stays consistent over time. Now you should have a good grasp of how to integrate C++ code coverage reports in your CI workflows with Codecov in order to ensure you won\u2019t fall behind on your coverage.\r\n\r\nAlthough the tutorial was specifically for Windows, Codecov is platform-agnostic and can be configured not only with other C++ toolchains but also other languages and code-hosting platforms.","post_title":"How to Set Up Codecov with C++ and GitHub Actions","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"how-to-set-up-codecov-with-c-plus-plus-and-github-actions","to_ping":"","pinged":"","post_modified":"2023-01-24 11:35:47","post_modified_gmt":"2023-01-24 16:35:47","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=5236","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[52],"tools":[230,200],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/06102021_How-to-Set-Up-Codecov-with-C-and-GitHub-Actions-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/06102021_How-to-Set-Up-Codecov-with-C-and-GitHub-Actions-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/how-to-set-up-codecov-with-c-plus-plus-and-github-actions\/","authorID":"56","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/imaculate-e1623337852530.jpeg","authorDisplayName":"Imaculate Mosha","authorURL":"https:\/\/app.miniextensions.com\/preview-record\/OigNE6xkuTAZNb6F5Pvj\/reczAo2gPjX2C5NRZ","cta":"Read Blog Post"},{"ID":4892,"post_author":"40","post_date":"2021-06-03 15:41:59","post_date_gmt":"2021-06-03 19:41:59","post_content":"Knowing the coverage of your codebase means knowing which parts of your code are covered by tests. It also gives you insight into how well-covered all the logical flows in your code are.\r\n\r\nBy writing unit tests alongside your code, you take your first steps toward ensuring the quality of your code and reducing the number of bugs in your codebase. To make sure the quality of the tests is good, you can invite colleagues to peer review the tests, and collaborate with subject matter experts to ensure that your test scenarios are covering as many cases as possible and also the most important ones. Getting an overview of your code coverage is a great way to automate the quality control of your tests even further.\r\n\r\nIn this article, we\u2019ll look at setting up automation to gather the code coverage of your C# codebase, inside your\u00a0<a href=\"https:\/\/azure.microsoft.com\/services\/devops\/pipelines\/\">Azure Pipelines setup<\/a>, and then send that data to\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>, a service that\u00a0<a href=\"https:\/\/about.codecov.io\/product\/features\/#source-code-coverage\">specializes in analyzing code coverage<\/a>.\r\n\r\nYou can follow along with the\u00a0<a href=\"https:\/\/github.com\/sebnilsson\/CodecovCsharpAzurePipelines\">sample GitHub project<\/a>\u00a0set up for this article. The solution structure mimics a small real-world project, with different classes and types with varying levels of code coverage.\r\n<h2 id=\"test-coverage-locally\">Test Coverage Locally<\/h2>\r\nFirst, you need to prepare the codebase that you\u2019ll be generating the code coverage for with the right\u00a0<a href=\"https:\/\/www.nuget.org\/packages\">NuGet packages<\/a>.\r\n\r\nThe standard template for Visual Studio or the .NET CLI for creating a new\u00a0<a href=\"https:\/\/docs.microsoft.com\/dotnet\/core\/testing\/unit-testing-with-dotnet-test\">xUnit test project<\/a>\u00a0will automatically add the package\u00a0<a href=\"https:\/\/www.nuget.org\/packages\/coverlet.collector\/\"><code>coverlet.collector<\/code><\/a>\u00a0to your test project. This is a framework for creating code coverage information for .NET.\r\n\r\nTo make sure you can use\u00a0<a href=\"https:\/\/github.com\/coverlet-coverage\/coverlet\">Coverlet<\/a>\u00a0to create the output in the format Codecov expects (<a href=\"https:\/\/github.com\/OpenCover\/opencover\">OpenCover<\/a>), you also need to add the NuGet package\u00a0<a href=\"https:\/\/www.nuget.org\/packages\/coverlet.msbuild\/\"><code>coverlet.msbuild<\/code><\/a>\u00a0to your test project.\r\n\r\nYou can verify that you've set everything up correctly in your test project by ensuring that you have at least one test in your project and then run the following command in your project:\r\n<pre><code>dotnet test \/<span class=\"hljs-selector-tag\">p<\/span>:CollectCoverage=true \/<span class=\"hljs-selector-tag\">p<\/span>:CoverletOutputFormat=opencover\r\n<\/code><\/pre>\r\nIf everything was set up correctly, the output of the command will show you how many tests were run, their statuses and the code coverage analyzed in your test project. The command should also result in an XML file in your test project's root folder named\u00a0<code>coverage.opencover.xml<\/code>.\r\n<h2 id=\"analysis-with-codecov\">Analysis with Codecov<\/h2>\r\nCodecov generated reports will help you navigate the multiple aspects of your source code's code coverage. To dive deeper into the details of the code coverage information in this XML file, you\u2019ll want to upload the file to Codecov.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/xi97kaF.jpg\" alt=\"Codecov\" \/>\r\n\r\nTo do this, first,\u00a0<a href=\"https:\/\/about.codecov.io\/sign-up\/\">sign in to Codecov<\/a>, which can be done through your account on GitHub, GitLab, or Bitbucket. This will allow you to quickly navigate to the repository you want to work with within Codecov.\r\n\r\nUnder each repository, you\u2019ll find the repository\u2019s Upload Token, which you will need later when you configure your Azure Pipelines.\r\n<h2 id=\"configure-azure-pipelines\">Configure Azure Pipelines<\/h2>\r\nTo ensure that your Azure Pipelines can send information to Codecov, you need to ensure that the pipeline has access to the\u00a0<code>codecov.exe<\/code>-file provided by Codecov. The easiest way to get started with this is by adding the\u00a0<a href=\"https:\/\/www.nuget.org\/packages\/Codecov\/\"><code>Codecov<\/code>\u00a0NuGet package<\/a>\u00a0to one of your projects.\r\n\r\nFor a more involved solution, you can install Codecov once on a build server you control, or at the start of a build, so that multiple steps in an advanced pipeline can use the same instance. One way to do this is by installing the\u00a0<a href=\"https:\/\/community.chocolatey.org\/packages\/codecov\">Codecov Chocolatey package<\/a>.\r\n\r\nWhen this is in place, you need to create a new pipeline in Azure Pipelines.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/sU4S3P6.jpg\" alt=\"Create a pipeline in Azure\" \/>\r\n\r\nYou will have to point your pipeline to the location of your repository. In this case, we\u2019ll point it toward the\u00a0<a href=\"https:\/\/github.com\/sebnilsson\/CodecovCsharpAzurePipelines\/blob\/main\/azure-pipelines.yml\"><code>azure-pipelines.yml<\/code>\u00a0file<\/a>, in the sample GitHub repository.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/889mx8g.jpg\" alt=\"Add a repository\" \/>\r\n\r\nHere are the most important parts of the\u00a0<code>azure-pipelines.yml<\/code>\u00a0file:\r\n<pre><code>poo<span class=\"hljs-variable\">l:<\/span>\r\n vmImage: <span class=\"hljs-string\">'windows-latest'<\/span>\r\n\r\nvariable<span class=\"hljs-variable\">s:<\/span>\r\n codecovVersion: <span class=\"hljs-string\">'1.12.4'<\/span>\r\n testProjec<span class=\"hljs-variable\">t:<\/span> <span class=\"hljs-string\">'CodecovCsharpAzurePipelines.Tests'<\/span>\r\n\r\nstep<span class=\"hljs-variable\">s:<\/span>\r\n- task: DotNetCoreCLI@<span class=\"hljs-number\">2<\/span>\r\n <span class=\"hljs-built_in\">input<\/span><span class=\"hljs-variable\">s:<\/span>\r\n <span class=\"hljs-keyword\">command<\/span>: <span class=\"hljs-string\">'restore'<\/span>\r\n displayName: <span class=\"hljs-string\">'.NET Restore'<\/span>\r\n\r\n- task: DotNetCoreCLI@<span class=\"hljs-number\">2<\/span>\r\n <span class=\"hljs-built_in\">input<\/span><span class=\"hljs-variable\">s:<\/span>\r\n <span class=\"hljs-keyword\">command<\/span>: <span class=\"hljs-string\">'test'<\/span>\r\n <span class=\"hljs-keyword\">argument<\/span><span class=\"hljs-variable\">s:<\/span> <span class=\"hljs-string\">'.\/test\/$(testProject)\/$(testProject).csproj -c Debug \/p:CollectCoverage=true \/p:CoverletOutputFormat=opencover'<\/span>\r\n displayName: <span class=\"hljs-string\">'.NET Test'<\/span>\r\n\r\n- <span class=\"hljs-keyword\">scrip<\/span><span class=\"hljs-variable\">t:<\/span> |\r\n %USERPROFILE%\\.nuget\\packages\\codecov\\$(codecovVersion)\\tools\\codecov.<span class=\"hljs-keyword\">exe<\/span> -<span class=\"hljs-keyword\">f<\/span> <span class=\"hljs-string\">\".\/test\/$(testProject)\/coverage.opencover.xml\"<\/span> -t $(CODECOV_TOKEN)\r\n displayName: <span class=\"hljs-string\">'Codecov'<\/span>\r\n<\/code><\/pre>\r\nUnder\u00a0<code>pool<\/code>, you can see that you\u2019re using the latest Windows version provided by Azure Pipelines, since you're targeting an\u00a0<code>.exe<\/code>\u00a0file coming from Codecov. This also ensures that potentially dynamic values are easily modified under\u00a0<code>variables<\/code>, with the version of the Codecov NuGet package you're using and the project name of the test project to use.\r\n\r\nThe\u00a0<code>steps<\/code>\u00a0start off restoring the NuGet packages of the solution and then proceed to run the\u00a0<code>dotnet test<\/code>\u00a0command with the correct parameters to create the coverage information into the XML file, which under the\u00a0<code>script<\/code>\u00a0step is then sent to Codecov. This is done by pointing to the\u00a0<code>codecov.exe<\/code>-file in the correct NuGet-path on the disk. The\u00a0<code>-t<\/code>-parameter is used to inject the Upload Token you get when you navigate your repository in Codecov.\r\n\r\nNext, you need to add a\u00a0<a href=\"https:\/\/docs.microsoft.com\/azure\/devops\/pipelines\/process\/variables\">variable<\/a>\u00a0for your pipeline with the name\u00a0<code>CODECOV_TOKEN<\/code>\u00a0and the value for the Upload Token found in Codecov.\r\n<h2 id=\"view-code-coverage\">View Code Coverage<\/h2>\r\nWhen your first build has passed successfully, you can start navigating your code in Codecov. You will quickly find that Codecov functionality is similar to GitHub, where you can see your commits, branches, and pull requests. Codecov, gives you additional code coverage-related data added to these views.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/6PwMgl5.jpg\" alt=\"Codecov\u2014Commits\" \/>\r\n\r\nFrom the overview, you can drill down into the code and get a summary of the code coverage of the individual files in your codebase. There you can see, per file, the number of lines of code tracked for coverage, as well as how many are covered, partly covered, or not covered at all, along with a percentage of code coverage per file, folder, and project.\r\n\r\nThis will help you get a good overview of the state of your code, with useful references to the specific section you're looking at and the project overall.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/GLp46ld.jpg\" alt=\"Codecov\u2014Code coverage\" \/>\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nHaving a check on your code coverage is crucial for any mature codebase. It enables you to have a more objective measurement of the quality of your unit tests and their test coverage of your code. It also helps you find blind spots in your code, which might not have enough testing scenarios to discover less-than-obvious bugs.\r\n\r\nTo analyze code coverage effectively, especially over time, you need tools to help you drill down into your code coverage reports. This helps you see parts of your codebase that can be improved as well as degradations of quality. This is where\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>\u00a0comes in. With Codecov, you can track the current state of your coverage and how it develops over time, directly in your workflow.","post_title":"How to Set Up Codecov with C# and Azure Pipelines","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"how-to-set-up-codecov-with-c-and-azure-pipelines","to_ping":"","pinged":"","post_modified":"2023-01-24 11:36:37","post_modified_gmt":"2023-01-24 16:36:37","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=4892","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[51],"tools":[385,273],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/06032021_How-to-Set-Up-Codecov-with-C-and-Azure-Pipelines-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/06032021_How-to-Set-Up-Codecov-with-C-and-Azure-Pipelines-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/how-to-set-up-codecov-with-c-and-azure-pipelines\/","authorID":"40","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/Sebastian-Nilsson-removebg-preview.png","authorDisplayName":"Sebastian Nilsson","authorURL":"https:\/\/www.linkedin.com\/in\/sebnilsson\/","cta":"Read Blog Post"},{"ID":4578,"post_author":"38","post_date":"2021-05-28 10:42:32","post_date_gmt":"2021-05-28 14:42:32","post_content":"No feeling beats testing your last function and all tests coming up green. I did a quick PR and sat back to sip my coffee while I waited for my PM's approval message.\r\n\r\nBut when I did hear the message chime, I saw this:\r\n<pre><code>\r\n`\r\n<\/code><\/pre>\r\n<em>\u2026What?<\/em>\r\n\r\nUnfortunately, writing tests and getting the coveted green check is not an indication that the task is complete. Imagine that the test you\u2019ve written only covers 50 percent of your code. Would a successful test result give you a satisfactory perspective of your codebase? Of course not. And that's why you need code coverage.\r\n<h2 id=\"what-is-code-coverage-and-why-is-it-important-for-java-developers-\">What Is Code Coverage and Why Is It Important for Java Developers?<\/h2>\r\nCode coverage is the measure of how much code is executed during testing. Simply put, it's the percentage of code covered by tests. A program with high code coverage has been thoroughly tested and has a lower chance of containing software bugs.\r\n\r\nCreating tests that cover the most important scenarios, paths, and edge cases give developers better insight into what parts of the codebase have been tested. This information comes in handy particularly when debugging. Obviously, increased test quality means increased product quality in the long run.\r\n\r\nIn this article, we\u2019ll talk about\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>, a code coverage tool available for GitHub, GitLab, and Bitbucket.\r\n<h2 id=\"setting-up-jacoco-with-jenkins-and-codecov\">Setting Up JaCoCo with Jenkins and Codecov<\/h2>\r\nIn this tutorial, you'll learn how to set up\u00a0<a href=\"https:\/\/github.com\/jacoco\/jacoco\">JaCoCo<\/a>, a free code coverage library written in Java, in a Java application. You\u2019ll use\u00a0<a href=\"https:\/\/www.jenkins.io\/\">Jenkins<\/a>, a continuous integration (CI) tool that allows continuous development, testing, and deployment of your software projects, and Codecov to analyze code coverage reports every time changes are pushed.\r\n<h3 id=\"running-tests-and-coverage-locally\">Running Tests and Coverage Locally<\/h3>\r\nTo run tests and coverage locally, you\u2019ll need to use a few tools. Start by creating a simple Java application in\u00a0<a href=\"https:\/\/www.jetbrains.com\/idea\/\">IntelliJ IDEA<\/a>\u00a0or your favorite Java IDE.\r\n<pre><code><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">AddSomeNumbers<\/span> {\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">addTwoNumbers<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">int<\/span> num1, <span class=\"hljs-keyword\">int<\/span> num2<\/span>)<\/span>{\r\n <span class=\"hljs-keyword\">return<\/span> num1 + num2;\r\n }\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span>(<span class=\"hljs-params\">String[] args<\/span>) <\/span>{\r\n AddSomeNumbers addSomeNumbers = <span class=\"hljs-keyword\">new<\/span> AddSomeNumbers();\r\n <span class=\"hljs-keyword\">int<\/span> sum = addSomeNumbers.addTwoNumbers(<span class=\"hljs-number\">404<\/span>,<span class=\"hljs-number\">204<\/span>);\r\n System.<span class=\"hljs-keyword\">out<\/span>.println(sum);\r\n }\r\n}\r\n<\/code><\/pre>\r\nThis is a simple class that houses a function that takes two integer numbers as input and returns their sum. Very simple and straightforward.\r\n\r\nNext, write a test case for this class.\r\n<pre><code>class <span class=\"hljs-keyword\">AddSomeNumbersTest <\/span>{\r\n\r\n @Test\r\n int <span class=\"hljs-keyword\">addTwoNumbers() <\/span>{\r\n <span class=\"hljs-keyword\">AddSomeNumbers <\/span><span class=\"hljs-keyword\">addSomeNumbers <\/span>= new <span class=\"hljs-keyword\">AddSomeNumbers();\r\n<\/span> int result = <span class=\"hljs-keyword\">addSomeNumbers.addTwoNumbers(50, <\/span><span class=\"hljs-number\">30<\/span>)<span class=\"hljs-comment\">;<\/span>\r\n assertEquals(<span class=\"hljs-number\">80<\/span>, result)<span class=\"hljs-comment\">;<\/span>\r\n return result<span class=\"hljs-comment\">;<\/span>\r\n }\r\n\r\n @Test\r\n void <span class=\"hljs-keyword\">shouldPrintSumToConsole(){\r\n<\/span> <span class=\"hljs-keyword\">AddSomeNumbers.main(new <\/span>String[] {})<span class=\"hljs-comment\">;<\/span>\r\n assertEquals(<span class=\"hljs-keyword\">addTwoNumbers(), <\/span><span class=\"hljs-number\">80<\/span>)<span class=\"hljs-comment\">;<\/span>\r\n }\r\n}\r\n<\/code><\/pre>\r\nThis is a simple unit test to test your\u00a0<code>AddSomeNumbers.java<\/code>\u00a0class as a component. To run your test, right-click on the green button next to your test class and click\u00a0<strong>Run<\/strong>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/F7AAJiC.png\" alt=\"AddSomeNumbers test\" \/>\r\n\r\nMake sure your test is passing before moving on to including coverage.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/lF9wRA2.png\" alt=\"Tests pass\" \/>\r\n\r\nCongratulations on writing your tests and getting the coveted green checks! Now you can proceed to configure Jenkins and JaCoCo for code coverage.\r\n<h3 id=\"configuring-jenkins\">Configuring Jenkins<\/h3>\r\nBefore moving forward, first, make sure your Jenkins installation is available on the internet. You can test locally by typing\u00a0<code>localhost:8080<\/code>, which is the default local IP address for Jenkins, into your browser. For installation details, refer to the\u00a0<a href=\"https:\/\/www.jenkins.io\/doc\/book\/installing\/\">\u201cInstalling Jenkins\u201d<\/a>\u00a0documentation.\r\n\r\nFirst, install the GitHub integration plugin. Go to\u00a0<strong>Manage Jenkins<\/strong>, then\u00a0<strong>Manage Plugins<\/strong>, then\u00a0<strong>Available<\/strong>, and finally in the search box type\u00a0<em>GitHub<\/em>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/Or7HjhZ.png\" alt=\"The Available tab in Jenkins\" \/>\r\n\r\nSelect the\u00a0<strong>GitHub Integration<\/strong>\u00a0plugin and click\u00a0<strong>Download now and install after restart<\/strong>. This will trigger the download of the plugin and all its dependencies. Wait for all plugins to be installed and Jenkins to be restarted.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/d2CatJQ.png\" alt=\"Downloading the GitHub Integration plugin\" \/>\r\n\r\nTo create a job, navigate to your Jenkins dashboard and click the\u00a0<em>*New Item<\/em>\u00a0tab at the top left. Give your job a suitable name or maintain the repository name.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/Up5Urmq.png\" alt=\"Enter an item name\" \/>\r\n\r\nSelect\u00a0<strong>Freestyle project<\/strong>\u00a0and click\u00a0<strong>OK<\/strong>\u00a0to continue.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/f6l06jZ.png\" alt=\"Selecting a Freestyle project\" \/>\r\n\r\nNext, you\u2019ll tell Jenkins that your project is hosted in GitHub by adding the URL of your GitHub project. Scroll down and select the\u00a0<strong>Git<\/strong>\u00a0radio button under the\u00a0<strong>Source Code Management<\/strong>\u00a0section.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/dPKhFdW.png\" alt=\"Entering your GitHub projects URL\" \/>\r\n\r\nPaste in your GitHub repository URL, or the URL that will be used to clone the project.\r\n\r\nScroll down to\u00a0<strong>Build Triggers<\/strong>. This section lets you tell Jenkins when it should start building your job. Since you want it to trigger a build any time something changes in GitHub, check the box next to\u00a0<strong>GitHub hook trigger for GITscm polling<\/strong>. This instructs Jenkins to listen for incoming requests from GitHub and trigger builds.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/thF67lE.png\" alt=\"Selecting build triggers\" \/>\r\n\r\nClick\u00a0<strong>Save<\/strong>.\r\n\r\nOne final thing: you need to ask GitHub to notify your Jenkins installation after every commit. Go to your GitHub repository, click\u00a0<strong>Settings<\/strong>, then\u00a0<strong>Webhook<\/strong>. This allows external services to be notified when certain events occur. Click\u00a0<strong>Add Webhook<\/strong>.\r\n\r\nNotice that a payload URL is required; this URL is the address of your Jenkins installation. Append\u00a0<code>\/github-webhook\/<\/code>\u00a0to it. For content type, choose\u00a0<strong>application\/json<\/strong>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/aw9ek2E.png\" alt=\"Webhook settings\" \/>\r\n\r\nIf you use\u00a0<code>localhost:8080<\/code>\u00a0as your URL address for your Jenkins installation, you\u2019ll notice that you bumped into some errors when setting up the hook. Localhost is a local IP address, but what GitHub needs is a public address. If you\u2019re not using a public IP,\u00a0<a href=\"https:\/\/ngrok.com\/\">ngrok<\/a>\u00a0is an ingenious way to achieve the same results with minimal effort.\r\n\r\nIf you used a secret for Jenkins installation, you\u2019ll have to use the same secret in the\u00a0<strong>Secret<\/strong>\u00a0field as shown in the previous image. If not, ignore it.\r\n\r\nSpecify that you want this webhook to be triggered when push events occur. To make your webhook active, check the\u00a0<strong>Active<\/strong>\u00a0checkbox. Click\u00a0<strong>Add webhook<\/strong>\u00a0to finish up.\r\n\r\nTest your whole workflow by making a commit.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/UIGSEQv.png\" alt=\"Your Jenkins build\" \/>\r\n\r\nA commit to your repository successfully triggers a build in Jenkins.\r\n<h3 id=\"setting-up-codecov-for-code-coverage-reporting\">Setting Up Codecov for Code Coverage Reporting<\/h3>\r\nBefore you add Codecov for your code coverage needs, you need JaCoCo. To add JaCoCo plugins to your root\u00a0<code>build.gradle<\/code>, add its dependencies.\r\n<pre><code>allprojects {\r\n apply plugin: <span class=\"hljs-string\">'java'<\/span>\r\n apply plugin: <span class=\"hljs-string\">'maven'<\/span>\r\n apply plugin: <span class=\"hljs-string\">'jacoco'<\/span>\r\n\r\n sourceCompatibility = <span class=\"hljs-number\">1.8<\/span>\r\n targetCompatibility = <span class=\"hljs-number\">1.8<\/span>\r\n\r\n repositories {\r\n mavenLocal()\r\n mavenCentral()\r\n jcenter()\r\n\r\n maven { url <span class=\"hljs-string\">\"https:\/\/repo1.maven.org\/maven2\/\"<\/span> }\r\n }\r\n}\r\n\r\nsubprojects {\r\n dependencies {\r\n\r\n }\r\n\r\n test.useTestNG()\r\n}\r\n\r\ntest {\r\n useJUnitPlatform()\r\n finalizedBy jacocoTestReport\r\n}\r\n\r\njacocoTestReport {\r\n dependsOn test\r\n reports {\r\n xml<span class=\"hljs-selector-class\">.enabled<\/span> true\r\n xml<span class=\"hljs-selector-class\">.destination<\/span> file(<span class=\"hljs-string\">\"${buildDir}\/reports\/jacoco\/report.xml\"<\/span>)\r\n <span class=\"hljs-selector-tag\">html<\/span><span class=\"hljs-selector-class\">.enabled<\/span> true\r\n csv<span class=\"hljs-selector-class\">.enabled<\/span> true\r\n }\r\n subprojects<span class=\"hljs-selector-class\">.each<\/span> {\r\n sourceSets it<span class=\"hljs-selector-class\">.sourceSets<\/span><span class=\"hljs-selector-class\">.main<\/span>\r\n }\r\n executionData fileTree(project<span class=\"hljs-selector-class\">.rootDir<\/span><span class=\"hljs-selector-class\">.absolutePath<\/span>).include(<span class=\"hljs-string\">\"**\/build\/jacoco\/*.exec\"<\/span>)\r\n}\r\n\r\ndependencies {\r\n implementation <span class=\"hljs-string\">'junit:junit:4.12'<\/span>\r\n implementation <span class=\"hljs-string\">'org.junit.jupiter:junit-jupiter:5.4.2'<\/span>\r\n}\r\n\r\njacocoTestReport<span class=\"hljs-selector-class\">.dependsOn<\/span> {\r\n subprojects*<span class=\"hljs-selector-class\">.test<\/span>\r\n}\r\n<\/code><\/pre>\r\nRun your tests by selecting coverage to test your JaCoCo workflow.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/IotL4sZ.png\" alt=\"JaCoCo coverage\" \/>\r\n\r\nYou should see test coverage results on your Class, Method, and Lines of code. To view your test results as HTML, navigate to\u00a0<strong>Build<\/strong>\u00a0-&gt;\u00a0<strong>Reports<\/strong>\u00a0-&gt;\u00a0<strong>JaCoCo<\/strong>\u00a0-&gt;\u00a0<strong>Test<\/strong>\u00a0-&gt;\u00a0<strong>HTML<\/strong>, right click on the\u00a0<code>index.html<\/code>\u00a0file, and select\u00a0<strong>Open with browser<\/strong>. Select any browser to view your coverage report in HTML.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/JzQRJwT.png\" alt=\"JaCoCo report\" \/>\r\n\r\nTo view your coverage reports in Jenkins, begin by configuring Gradle for Jenkins. Head over to your Jenkins dashboard, select\u00a0<strong>Manage Jenkins<\/strong>, navigate to\u00a0<strong>Global Tool Configuration<\/strong>, and select\u00a0<strong>Gradle installation<\/strong>. Add the path to your Gradle and give it a name. While it could be anything memorable to you,\u00a0<code>GRADLE_HOME<\/code>\u00a0sounds decent enough. Uncheck\u00a0<strong>Install automatically<\/strong>\u00a0and save your changes.\r\n\r\n!Gradle installations options](<a href=\"https:\/\/i.imgur.com\/0IDqL3Q.png\">https:\/\/i.imgur.com\/0IDqL3Q.png<\/a>)\r\n\r\nTo include your build steps as part of your Jenkins build setup, navigate to your Jenkins Dashboard and select your project. On the far left of the dashboard, choose\u00a0<strong>Configure<\/strong>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/Z351Eew.png\" alt=\"Configure Jenkins\" \/>\r\n\r\nScroll down to the\u00a0<strong>Build<\/strong>\u00a0section of the page and select the radio button for\u00a0<strong>Use Gradle Wrapper<\/strong>. Under\u00a0<strong>Tasks<\/strong>, write your Gradle build script.\u00a0<code>clean build<\/code>\u00a0should trigger builds to compile the source code, run the tests, and assemble the JAR artifact.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/uoCcZYB.png\" alt=\"Jenkins build\" \/>\r\n\r\nBuild your project to test the whole workflow.\r\n\r\nTo view your post-build actions including coverage reports, navigate to\u00a0<strong>Post-build Actions<\/strong>, click\u00a0<strong>Add post-build action<\/strong>\u00a0and select a Jacoco coverage report as shown in the following image. Jenkins should do the rest of the setup for you by default.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/NqXfTfO.png\" alt=\"Post-build Jenkins\" \/>\r\n\r\nRun your build again. You should see your JaCoCo coverage report summary published on Jenkins.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/MY88Afs.png\" alt=\"Jenkins report\" \/>\r\n<h3 id=\"viewing-code-coverage-in-codecov\">Viewing Code Coverage in Codecov<\/h3>\r\nIn order to use Codecov, you\u2019ll need to sign up at the official site, or you can opt for the\u00a0<a href=\"https:\/\/about.codecov.io\/sign-up\/\">GitHub sign-up option<\/a>. Once you\u2019ve signed in, select your repository.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/IzL64LD.png\" alt=\"Selecting a repository for Codecov\" \/>\r\n\r\nAfter selecting your desired repository, you should see your Codecov dashboard. Note that when using GitHub Actions with Codecov, you'll need a unique upload token as shown in the following image. This token is useful only if your repository is private. The token is required to identify which project the coverage belongs to.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/DFWbcaI.png\" alt=\"Your Codecov dashboard and Upload Token\" \/>\u00a0Great! Now head over to your IDE and create a\u00a0<code>jenkins.yml<\/code>\u00a0file in your root project directory under\u00a0<strong>.github<\/strong>\u00a0-&gt;\u00a0<strong>workflows<\/strong>, and add the following script:\r\n<pre><code><span class=\"hljs-attribute\">name<\/span>: Jenkins CI\r\n\r\n<span class=\"less\"><span class=\"hljs-attribute\">on<\/span>:\r\n <span class=\"hljs-attribute\">push<\/span>:\r\n <span class=\"hljs-attribute\">branches<\/span>: [ main ]\r\n <span class=\"hljs-attribute\">pull_request<\/span>:\r\n <span class=\"hljs-attribute\">branches<\/span>: [ main ]\r\n\r\n<span class=\"hljs-attribute\">jobs<\/span>:\r\n <span class=\"hljs-attribute\">build<\/span>:\r\n\r\n <span class=\"hljs-attribute\">runs-on<\/span>: ubuntu-latest\r\n\r\n <span class=\"hljs-attribute\">steps<\/span>:\r\n - <span class=\"hljs-attribute\">uses<\/span>: actions\/checkout<span class=\"hljs-variable\">@v2<\/span>\r\n - <span class=\"hljs-attribute\">name<\/span>: Set up JDK <span class=\"hljs-number\">11<\/span>\r\n <span class=\"hljs-attribute\">uses<\/span>: actions\/setup-java<span class=\"hljs-variable\">@v2<\/span>\r\n <span class=\"hljs-attribute\">with<\/span>:\r\n <span class=\"hljs-attribute\">java-version<\/span>: <span class=\"hljs-string\">'11'<\/span>\r\n <span class=\"hljs-attribute\">distribution<\/span>: <span class=\"hljs-string\">'adopt'<\/span>\r\n - <span class=\"hljs-attribute\">name<\/span>: Grant execute permission for gradlew\r\n <span class=\"hljs-attribute\">run<\/span>: chmod +x gradlew\r\n - <span class=\"hljs-attribute\">name<\/span>: Build with Gradle\r\n <span class=\"hljs-attribute\">run<\/span>: .\/gradlew clean build\r\n\r\n <span class=\"hljs-attribute\">test<\/span>:\r\n <span class=\"hljs-attribute\">runs-on<\/span>: ubuntu-latest\r\n <span class=\"hljs-attribute\">steps<\/span>:\r\n - <span class=\"hljs-attribute\">uses<\/span>: actions\/checkout<span class=\"hljs-variable\">@v2<\/span>\r\n - <span class=\"hljs-attribute\">name<\/span>: Run tests\r\n <span class=\"hljs-attribute\">run<\/span>: .\/gradlew clean build\r\n - <span class=\"hljs-attribute\">name<\/span>: Coverage Report\r\n <span class=\"hljs-attribute\">run<\/span>: .\/gradlew jacocoTestReport\r\n - <span class=\"hljs-attribute\">name<\/span>: Upload coverage to Codecov\r\n <span class=\"hljs-attribute\">uses<\/span>: codecov\/codecov-action<span class=\"hljs-variable\">@v2<\/span>\r\n <span class=\"hljs-attribute\">with<\/span>:\r\n <span class=\"hljs-attribute\">fail_ci_if_error<\/span>: false<\/span>\r\n<\/code><\/pre>\r\nHere, you\u2019re defining a job called\u00a0<code>build<\/code>\u00a0that\u2019s going to compile the source code and run your tests.\r\n\r\nIn the test job, you\u2019ve defined three steps:\r\n<ul>\r\n \t<li>one to run the test with coverage<\/li>\r\n \t<li>one to generate the coverage report<\/li>\r\n \t<li>one to upload the coverage to Codecov<\/li>\r\n<\/ul>\r\nTo test the whole workflow, push a new commit, and your workflow will start. A successful build on Jenkins should upload your Jacoco coverage report to Codecov as shown in the following image.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/ft1wBW4.png\" alt=\"Passing build\" \/>\r\n\r\nSatisfying, right?\r\n\r\nNow you\u2019ve successfully written tests and used Codecov to give you a comprehensive coverage report with actionable insights to ensure you are shipping quality code.\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nThe importance of testing and code coverage cannot be overemphasized. Code coverage allows you to see what you tested, what you missed, and why or how, as well as give you confidence in the quality of your code.\r\n\r\nBy now, you should be equipped to run local tests and use code coverage tools like Jenkins and JaCoCo. You can configure Jenkins and integrate it with a GitHub repository using webhooks. And you know how to set up\u00a0<a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a>\u00a0as a code coverage reporting tool, making the process more visual and simple to activate on.","post_title":"How to Set Up Codecov with Java and Jenkins","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"how-to-set-up-codecov-with-java-and-jenkins","to_ping":"","pinged":"","post_modified":"2023-01-24 11:40:29","post_modified_gmt":"2023-01-24 16:40:29","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=4578","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[63],"tools":[243,76],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/05282021_How-to-Set-Up-Codecov-with-Java-and-Jenkins-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/05282021_How-to-Set-Up-Codecov-with-Java-and-Jenkins-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/how-to-set-up-codecov-with-java-and-jenkins\/","authorID":"38","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/04\/derrick-removebg-preview.png","authorDisplayName":"Derrick Wadek","authorURL":"https:\/\/www.linkedin.com\/in\/derrick-wadek-166a889b\/","cta":"Read Blog Post"},{"ID":4882,"post_author":"7","post_date":"2021-05-12 10:51:37","post_date_gmt":"2021-05-12 14:51:37","post_content":"This tutorial walks through how to upload coverage reports in a separate job on GitHub Actions. Although all developers can benefit from doing this, we recommend it most for users that do the following:\r\n<ol>\r\n \t<li>Upload more than 100 uploads per commit<\/li>\r\n \t<li>Need a separation in responsibility between jobs, and\/or<\/li>\r\n \t<li>Want to control uploads to Codecov as a single final step.<\/li>\r\n<\/ol>\r\nTo do this, we'll be using GitHub's <a href=\"https:\/\/github.com\/actions\/upload-artifact\" target=\"_blank\" rel=\"noopener\">actions\/upload-artifact<\/a> and <a href=\"https:\/\/github.com\/actions\/download-artifact\" target=\"_blank\" rel=\"noopener\">actions\/download-artifact<\/a>. All of the code for this post can be found in our <a href=\"https:\/\/github.com\/codecov\/example-actions-bundled\" target=\"_blank\" rel=\"noopener\">example repository<\/a>.\r\n<h3>Saving artifacts<\/h3>\r\nGitHub provides an action to upload artifacts in the same workflow. We use this to temporarily store coverage reports before uploading them to Codecov. We can add the following code at the end of a job that tests and collects coverage for a subset of tests.\r\n<pre class=\"hljs yaml\"><code> - uses: actions\/upload-artifact@v2\r\n with:\r\n name: {{ any_descriptive_name }}\r\n path: {{ path\/to\/coverage\/report }}<\/code><\/pre>\r\nThis will upload the coverage report at the given path to a specific name. The name attribute is not required and the path can be a directory, a wildcard selector, or a list of files.\r\n\r\nIf you are having trouble finding the coverage report path, and you have uploaded coverage to Codecov previously, you can find the file in the Codecov output:\r\n<pre class=\"hljs bash\"><code>==&gt; Reading reports\r\n+ .\/coverage.xml\r\n<\/code><\/pre>\r\nIn this case, the coverage report is found at <code>.\/coverage.xml<\/code>, and we can use the following snippet in our job\r\n<pre class=\"hljs yaml\"><code> - uses: actions\/upload-artifact@v2\r\n with:\r\n name: backend-coverage\r\n path: .\/coverage.xml<\/code><\/pre>\r\n<h3>Creating the Codecov job<\/h3>\r\nThe Codecov job can be written as a dependency to the applicable coverage jobs.\r\n<pre class=\"hljs yaml\"><code>jobs:\r\n ...\r\n upload-to-codecov:\r\n needs: [ {{ names-of-jobs }} ]\r\n steps:\r\n - name: Checkout\r\n uses: actions\/checkout@v2\r\n<\/code><\/pre>\r\nIn the example repository, we have two jobs, <code>frontend-tests<\/code> and <code>backend-tests<\/code> that upload artifacts. Our code snippet becomes\r\n<pre class=\"hljs yaml\"><code>jobs:\r\n ...\r\n upload-to-codecov:\r\n needs: [ frontend-tests, backend-tests ]\r\n steps:\r\n - name: Checkout\r\n uses: actions\/checkout@v2\r\n<\/code><\/pre>\r\n<h3>Downloading artifacts<\/h3>\r\nThe Codecov job will need access to the artifacts. We can use <code>actions\/download-artifact<\/code> to do this.\r\n<pre class=\"hljs yaml\"><code> - name: Download artifacts\r\n uses: actions\/download-artifact@v2\r\n<\/code><\/pre>\r\n<h3>Using the Codecov Action<\/h3>\r\nWe are now set to upload coverage reports to Codecov. We can use the <a href=\"https:\/\/github.com\/codecov\/codecov-action\" target=\"_blank\" rel=\"noopener\">Codecov GitHub Action<\/a> to do this.\r\n<pre class=\"hljs yaml\"><code> - name: Upload to Codecov\r\n uses: codecov\/codecov-action@v2\r\n<\/code><\/pre>\r\n<h3>Summary<\/h3>\r\nWith these code changes, we can upload coverage reports as a single job to Codecov. The entire job looks like this\r\n<pre class=\"hljs yaml\"><code>steps:\r\n ...\r\n upload-to-codecov:\r\n needs: [frontend-tests, backend-tests]\r\n runs-on: ubuntu-latest\r\n steps:\r\n - name: Checkout\r\n uses: actions\/checkout@v2\r\n - name: Download artifacts\r\n uses: actions\/download-artifact@v2\r\n - name: Upload to Codecov\r\n uses: codecov\/codecov-action@v2\r\n<\/code><\/pre>\r\nTo see the final product in action, check out the <a href=\"https:\/\/github.com\/codecov\/example-actions-bundled\/actions\/runs\/821451385\" target=\"_blank\" rel=\"noopener\">workflow<\/a> or the example repository above.","post_title":"Uploading Code Coverage in a Separate Job on GitHub Actions","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"uploading-code-coverage-in-a-separate-job-on-github-actions","to_ping":"","pinged":"","post_modified":"2022-03-16 12:37:36","post_modified_gmt":"2022-03-16 16:37:36","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=4882","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":false,"tools":[241,230],"image":false,"featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/06\/1Uploading-Code-Coverage-in-a-Separate-Job-on-GitHub-Actions-.png","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/uploading-code-coverage-in-a-separate-job-on-github-actions\/","authorID":"7","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/tom-hu.png","authorDisplayName":"Tom Hu","authorURL":"https:\/\/www.linkedin.com\/in\/thomasrockhu\/","cta":"Read Blog Post"},{"ID":4727,"post_author":"7","post_date":"2021-05-05 11:01:59","post_date_gmt":"2021-05-05 15:01:59","post_content":"In response to the <a href=\"https:\/\/about.codecov.io\/security-update\/\" target=\"_blank\" rel=\"noopener\">bash security update<\/a>, Codecov has added steps to make it easier to validate the bash uploader. As an additional layer of security, users may wish to check the script against the provided SHASUMs. This document shares current best practices to validate the script locally and on CI\/CDs.\r\n<h2><b>Adding a validation step<\/b><\/h2>\r\nThe below code snippet can be used to validate the downloaded bash script\r\n<pre class=\"hljs bash\"><code>curl -fLso codecov https:\/\/codecov.io\/bash;\r\nVERSION=$(grep -o 'VERSION=\\\"[0-9\\.]*\\\"' codecov | cut -d'\"' -f2);\r\nfor i in 1 256 512\r\ndo\r\n shasum -a $i -c --ignore-missing &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM\")\r\ndone<\/code><\/pre>\r\nThe above snippet does the following:\r\n<ul>\r\n \t<li>The first line downloads the script and stores it as <code>codecov<\/code>.<\/li>\r\n \t<li>Since we are always pushing updates to the script, the second line greps for the version and assigns it to the VERSION variable.<\/li>\r\n \t<li>Codecov provides SHASUM1, SHASUM256, and SHASUM512 checksums on GitHub. The following lines check all 3 of these checksums against the <code>codecov<\/code> script.<\/li>\r\n<\/ul>\r\n&nbsp;\r\n<h2><b>Handling older shasum versions<\/b><\/h2>\r\nOlder versions of <code>shasum<\/code> do not support the <code>--ignore-missing<\/code> option. For all code snippets provided below, we assume that the latest version is available. For users where this is not possible, the alternative to\r\n<pre class=\"hljs bash\"><code>shasum -a $i -c --ignore-missing &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM\")\r\n<\/code><\/pre>\r\nis\r\n<pre class=\"hljs bash\"><code>shasum -a $i -c &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM\" | grep -w \u201ccodecov\u201d)<\/code><\/pre>\r\nIf you are unable to test the <code>shasum<\/code> version, you can run\r\n<pre class=\"hljs bash\"><code>shasum -a $i -c --ignore-missing &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM) ||\r\nshasum -a $i -c &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM | grep -w \u201ccodecov\u201d)\r\n<\/code><\/pre>\r\n&nbsp;\r\n<h2><b>GitHub Actions<\/b><\/h2>\r\nWe recommend using the latest versions of <a href=\"https:\/\/github.com\/marketplace\/actions\/codecov\" target=\"_blank\" rel=\"noopener\">Codecov Action<\/a> since it uses a local, validated copy of the bash script. For users that cannot or wish to use the bash uploader, you can update your workflows from\r\n<pre class=\"hljs bash\"><code>\u00a0\u00a0- name: Upload coverage reports to Codecov\r\n\u00a0\u00a0\u00a0\u00a0run: bash &lt;(curl -s https:\/\/codecov.io\/bash)\r\n<\/code><\/pre>\r\nto\r\n<pre class=\"hljs bash\"><code>\u00a0\u00a0- name: Download and validate Codecov script\r\n\u00a0\u00a0\u00a0\u00a0run: |\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0curl -fLso codecov https:\/\/codecov.io\/bash;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VERSION=$(grep -o 'VERSION=\\\"[0-9\\.]*\\\"' codecov | cut -d'\"' -f2);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for i in 1 256 512\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0do\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0shasum -a $i -c --ignore-missing &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM\")\r\n done\r\n\u00a0\u00a0- name: Upload coverage reports to Codecov\r\n\u00a0\u00a0\u00a0\u00a0run: bash .\/codecov\r\n<\/code><\/pre>\r\n&nbsp;\r\n<h2><b>CircleCI<\/b><\/h2>\r\nWe recommend using the <a href=\"https:\/\/circleci.com\/developer\/orbs\/orb\/codecov\/codecov\" target=\"_blank\" rel=\"noopener\">Codecov CircleCI Orb<\/a> as it contains the supplied validation of the bash script. For users that cannot or wish to use the bash uploader, you can update your workflows from\r\n<pre class=\"hljs bash\"><code> - run:\r\n name: Upload coverage reports to Codecov\r\n command: |\r\n bash &lt;(curl -s https:\/\/codecov.io\/bash)\r\n<\/code><\/pre>\r\nto\r\n<pre class=\"hljs bash\"><code> - run:\r\n name: Download and validate Codecov script\r\n command: |\r\n curl -fLso codecov https:\/\/codecov.io\/bash;\r\n VERSION=$(grep -o 'VERSION=\\\"[0-9\\.]*\\\"' codecov | cut -d'\"' -f2);\r\n for i in 1 256 512\r\n do\r\n shasum -a $i -c --ignore-missing &lt;(curl -s \"https:\/\/raw.githubusercontent.com\/codecov\/codecov-bash\/${VERSION}\/SHA${i}SUM\")\r\n done\r\n - run:\r\n name: Upload coverage reports to Codecov\r\n command: bash .\/codecov\r\n<\/code><\/pre>","post_title":"Validating the Bash Script on CI","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"validating-the-bash-script-on-ci","to_ping":"","pinged":"","post_modified":"2021-05-05 11:28:15","post_modified_gmt":"2021-05-05 15:28:15","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=4727","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[50],"tools":[74,230],"image":false,"featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/12.Validating-the-bash-script-on-CI-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/validating-the-bash-script-on-ci\/","authorID":"7","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/tom-hu.png","authorDisplayName":"Tom Hu","authorURL":"https:\/\/www.linkedin.com\/in\/thomasrockhu\/","cta":"Read Blog Post"},{"ID":4344,"post_author":"4","post_date":"2021-03-18 19:07:31","post_date_gmt":"2021-03-18 19:07:31","post_content":"<p class=\"lead\">In this webinar we will explore the tools, processes and best practices required to make code coverage part of your CI workflow.<\/p>\r\nAdditionally, we will cover how you can integrate Codecov with Codefresh to automate your code coverage reports and improve your code quality.\r\n<h3>We will also explore:<\/h3>\r\n<ul>\r\n \t<li>Codecov\u2019s new <a href=\"https:\/\/codefresh.io\/steps\/step\/codecov-reporter\">Codefresh \u201cstep\u201d<\/a><\/li>\r\n \t<li>Difficulties assessing code coverage metrics on their own<\/li>\r\n \t<li>Why good coverage does not equal good tests<\/li>\r\n \t<li>What constitutes a good code coverage target<\/li>\r\n \t<li>Whether it makes sense to aim for a 100% code coverage<\/li>\r\n<\/ul>","post_title":"Increase Code Coverage With Codefresh and Codecov","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"increase-code-coverage-with-codefresh-and-codecov","to_ping":"","pinged":"","post_modified":"2025-01-17 16:15:38","post_modified_gmt":"2025-01-17 21:15:38","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?post_type=event&#038;p=4344","menu_order":0,"post_type":"resource","post_mime_type":"","comment_count":"0","filter":"raw","language":false,"tools":[241,289],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/03\/cover-2.png","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/03\/cover-2.png","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"On-Demand Webinar","permalink":"https:\/\/about.codecov.io\/resource\/increase-code-coverage-with-codefresh-and-codecov\/","authorID":"4","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/05\/jerrod-engelberd.png","authorDisplayName":"Jerrod Engelberg","authorURL":"https:\/\/www.linkedin.com\/in\/jerrodengelberg\/","cta":"Watch Webinar"},{"ID":4227,"post_author":"31","post_date":"2021-03-03 20:26:09","post_date_gmt":"2021-03-03 20:26:09","post_content":"<p class=\"lead\">You know testing your code is important\u2014but how effective are your tests? How many lines of code does it address, and does it touch enough of the subroutines? <em>Code coverage<\/em> is the measurement of how much of your source code a test covers, and understanding it can go a long way toward being confident in your test results.<\/p>\r\n\r\n<h2 id=\"how-do-i-understand-my-code-coverage-\">How Do I Understand My Code Coverage?<\/h2>\r\nReporting tools like <a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a> can take your code coverage report and turn it into meaningful data, like how pull requests will affect code coverage. Codecov works in tandem with your <a href=\"https:\/\/docs.codecov.io\/docs\/ci-service-relationship\">continuous integration (CI) system<\/a> to analyze every commit, so you get insight into how your tests are performing right in your own workflow.\r\n\r\nIn short, knowing your percentage of code coverage, and what it means, can help you write better tests for your apps, which leads to building better apps. In this article, you\u2019ll learn how to integrate <a href=\"https:\/\/github.com\/jacoco\/jacoco\">JaCoCo<\/a>, a free code coverage library in Java, into your Android project, then generate a report for analysis with Codecov. If you\u2019d like, you can check out <a href=\"https:\/\/github.com\/wise4rmgod\/CodeCoverage_Example\">this tutorial\u2019s GitHub repo<\/a>.\r\n<h2 id=\"implementing-code-coverage-in-android\">Implementing Code Coverage in Android<\/h2>\r\nFirst, let\u2019s walk through how to implement code coverage in your Android project. You\u2019ll write a unit test, add JaCoCo to your project, and automate the process using <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a>.\r\n\r\nTo begin, make sure you\u2019re familiar with the following prerequisites:\r\n<ul>\r\n \t<li>GitHub Actions<\/li>\r\n \t<li>Kotlin<\/li>\r\n \t<li>Android Studio 4.2<\/li>\r\n<\/ul>\r\nThen it\u2019s time to write some unit tests for your project so JaCoCo can generate a report for you:\r\n<pre><code> <span class=\"hljs-meta\">@Test<\/span>\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">fun<\/span> <span class=\"hljs-title\">counttext<\/span><span class=\"hljs-params\">()<\/span><\/span> {\r\n <span class=\"hljs-keyword\">val<\/span> yu = TextMethods.counttext(<span class=\"hljs-string\">\"tuuuuu\"<\/span>, <span class=\"hljs-string\">\"\"<\/span>)\r\n <span class=\"hljs-comment\">\/\/ assertTrue(\"text contains two characters\", yu == 2)<\/span>\r\n <span class=\"hljs-comment\">\/\/ assertNotNull(\"text is not null\", yu)<\/span>\r\n assertThat(yu).isGreaterThan(<span class=\"hljs-number\">4<\/span>)\r\n\r\n }\r\n\r\n <span class=\"hljs-meta\">@Test<\/span>\r\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">fun<\/span> <span class=\"hljs-title\">capitalizeText<\/span><span class=\"hljs-params\">()<\/span><\/span> {\r\n <span class=\"hljs-keyword\">val<\/span> yu = TextMethods.capitalizeText(<span class=\"hljs-string\">\"tuuuuu\"<\/span>, <span class=\"hljs-string\">\"\"<\/span>)\r\n assertThat(yu).contains(<span class=\"hljs-string\">\"TUUUUU\"<\/span>)\r\n }\r\n<\/code><\/pre>\r\nNow, add JaCoCo to your project.\r\n\r\n<strong>Gradle project level<\/strong>\r\n<pre><code><span class=\"hljs-comment\">\/\/ Top-level build file where you can add configuration options common to all sub-projects\/modules.<\/span>\r\n<span class=\"hljs-keyword\">buildscript<\/span> {\r\n ext.kotlin_version = <span class=\"hljs-string\">\"1.4.21\"<\/span>\r\n ext.jacocoVersion = <span class=\"hljs-string\">'0.8.4'<\/span>\r\n <span class=\"hljs-keyword\">repositories<\/span> {\r\n google()\r\n jcenter()\r\n }\r\n <span class=\"hljs-keyword\">dependencies<\/span> {\r\n <span class=\"hljs-keyword\">classpath<\/span> <span class=\"hljs-string\">\"com.android.tools.build:gradle:4.1.2\"<\/span>\r\n <span class=\"hljs-keyword\">classpath<\/span> <span class=\"hljs-string\">\"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"<\/span>\r\n <span class=\"hljs-keyword\">classpath<\/span> <span class=\"hljs-string\">\"org.jacoco:org.jacoco.core:$jacocoVersion\"<\/span>\r\n <span class=\"hljs-comment\">\/\/ <span class=\"hljs-doctag\">NOTE:<\/span> Do not place your application dependencies here; they belong<\/span>\r\n <span class=\"hljs-comment\">\/\/ in the individual module build.gradle files<\/span>\r\n }\r\n}\r\n<\/code><\/pre>\r\n<strong>Gradle module level<\/strong>\r\n<pre><code><span class=\"hljs-keyword\">plugins<\/span> {\r\n <span class=\"hljs-built_in\">id<\/span> <span class=\"hljs-string\">'com.android.application'<\/span>\r\n <span class=\"hljs-built_in\">id<\/span> <span class=\"hljs-string\">'kotlin-android'<\/span>\r\n <span class=\"hljs-built_in\">id<\/span> <span class=\"hljs-string\">'jacoco'<\/span>\r\n}\r\n\r\n<span class=\"hljs-keyword\">task<\/span> <span class=\"hljs-keyword\">jacocoTestReport<\/span>(type: JacocoReport, dependsOn: [<span class=\"hljs-string\">'testDebugUnitTest'<\/span>, <span class=\"hljs-string\">'createDebugCoverageReport'<\/span>]) {\r\n\r\n <span class=\"hljs-keyword\">reports<\/span> {\r\n xml.<span class=\"hljs-literal\">enabled<\/span> = <span class=\"hljs-keyword\">true<\/span>\r\n html.<span class=\"hljs-literal\">enabled<\/span> = <span class=\"hljs-keyword\">true<\/span>\r\n }\r\n\r\n <span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-keyword\">fileFilter<\/span> = [<span class=\"hljs-string\">'**\/R.class'<\/span>, <span class=\"hljs-string\">'**\/R$*.class'<\/span>, <span class=\"hljs-string\">'**\/BuildConfig.*'<\/span>, <span class=\"hljs-string\">'**\/Manifest*.*'<\/span>, <span class=\"hljs-string\">'**\/*Test*.*'<\/span>, <span class=\"hljs-string\">'android\/**\/*.*'<\/span>]\r\n def debugTree = fileTree(dir: <span class=\"hljs-string\">\"${buildDir}\/intermediates\/classes\/debug\"<\/span>, excludes: fileFilter)\r\n def mainSrc = <span class=\"hljs-string\">\"${project.projectDir}\/src\/main\/java\"<\/span>\r\n\r\n sourceDirectories.setFrom(files([mainSrc]))\r\n classDirectories.setFrom(files([debugTree]))\r\n executionData.setFrom(fileTree(dir: <span class=\"hljs-string\">\"<span class=\"hljs-variable\">$buildDir<\/span>\"<\/span>, includes: [\r\n <span class=\"hljs-string\">\"jacoco\/testDebugUnitTest.exec\"<\/span>,\r\n <span class=\"hljs-string\">\"outputs\/code-coverage\/connected\/*coverage.ec\"<\/span>\r\n ]))\r\n}\r\n\r\n<span class=\"hljs-keyword\">testOptions<\/span> {\r\n unitTests.all {\r\n jacoco {\r\n includeNoLocationClasses = <span class=\"hljs-keyword\">true<\/span>\r\n }\r\n }\r\n unitTests.returnDefaultValues = true\r\n }\r\n\r\n\r\n <span class=\"hljs-keyword\">buildTypes<\/span> {\r\n debug {\r\n testCoverageEnabled <span class=\"hljs-keyword\">true<\/span>\r\n }\r\n <span class=\"hljs-keyword\">release<\/span> {\r\n minifyEnabled <span class=\"hljs-keyword\">false<\/span>\r\n proguardFiles getDefaultProguardFile(<span class=\"hljs-string\">'proguard-android-optimize.txt'<\/span>), <span class=\"hljs-string\">'proguard-rules.pro'<\/span>\r\n }\r\n }\r\n<\/code><\/pre>\r\nSync your project in <a href=\"https:\/\/developer.android.com\/studio\">Android Studio<\/a> to include the JaCoCo Gradle task and classes that will enable you to generate code coverage for your app.\r\n\r\nAfter enabling JaCoCo in your project, generate your first code coverage in HTML format. The following Gradle command will generate a test coverage report for your project:\r\n<pre><code><span class=\"hljs-selector-class\">.gradlew<\/span> connectedCheck\r\n<\/code><\/pre>\r\nThis will generate a report for your unit test alone:\r\n<pre><code><span class=\"hljs-selector-class\">.gradlew<\/span> testDebugUnitTest\r\n<\/code><\/pre>\r\nAnd this will generate the report for an instrumented test:\r\n<pre><code><span class=\"hljs-selector-class\">.gradlew<\/span> connectedDebugAndroidTest\r\n<\/code><\/pre>\r\nYou can check the code coverage report of your instrumented and unit tests locally. For your instrumented test, locate your Android studio projects folder in your system. Then navigate to your project folder: _(CodeCoverage<em>Example) &gt; app &gt; build &gt; reports &gt; androidTests &gt; connected &gt; flavors &gt; debugAndroidTest &gt; Index.html<\/em>.\r\n\r\nYou\u2019ll arrive at this screen after clicking <em>Index.html<\/em> to view the report on your web browser:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/fh11g6s.png\" alt=\"Instrumented test report\" \/>\r\n\r\nFor the unit test, navigate to <em>\u2026reports &gt; tests &gt; testDebugUnitTest &gt; Index.html<\/em>. After clicking on <em>index.html<\/em>, you\u2019ll see the following screen:\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/2Qxvzsq.png\" alt=\"Unit test report\" \/>\r\n\r\nTo see the test result, navigate to _com.dev.codecoverage<em>example.util &gt; TestMethodsTest<\/em>. To send a code coverage report to Codecov, first navigate to <em>coverage &gt; debug &gt; index.html<\/em> to choose a supported file format.\r\n\r\n<img class=\"alignnone wp-image-4270 size-full\" src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/03\/local-code-coverage-e1614791827111.png\" alt=\"\" width=\"3576\" height=\"572\" \/>\r\n\r\nFinally, let\u2019s push your project to GitHub.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/uxYtk8v.png\" alt=\"Sample code coverage GitHub project\" \/>\r\n\r\nBefore setting up GitHub Actions as the CI for your project, there are a few terms you should know to help you understand CI\/CD using GitHub Actions:\r\n<ul>\r\n \t<li><strong>Job:<\/strong> A job in GitHub Actions contains a sequence of tasks called <em>steps<\/em>.<\/li>\r\n \t<li><strong>Steps:<\/strong> Steps can run commands.<\/li>\r\n \t<li><strong>Workflow:<\/strong> A workflow is a configurable automated process made up of one or more <em>jobs<\/em>.<\/li>\r\n<\/ul>\r\nTo add GitHub Actions to your workflow, click the <em>Actions<\/em> tab at the top of your repository window.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/oCXljnb.png\" alt=\"Click Actions at the top of the screen\" \/>\r\n\r\nSelect a workflow template from the list that matches your programming language or tool.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/h14dVZx.png\" alt=\"List of Github Actions workflow templates\" \/>\r\n\r\nClick <em>Set up this workflow<\/em> to add Github Actions to your project.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/ZPnvOG2.png\" alt=\"Set up this workflow\" \/>\r\n\r\nClick <em>Start commit<\/em>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/HhqolcU.png\" alt=\"The green Start commit button\" \/>\r\n\r\nThen name your file and click <em>Commit new file<\/em> to commit to the main branch or create a new branch.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/xz2WsJt.png\" alt=\"The Commit new file window\" \/>\r\n\r\nYou can decide to edit the GitHub Actions workflow before committing your new file, but for this tutorial, commit the default workflow to the <code>master<\/code> branch and modify it later.\r\n\r\nNext, let\u2019s integrate the Codecov plugin into your project in GitHub so you can push a test report to Codecov. First, navigate on your browser to <a href=\"https:\/\/github.com\/apps\/codecov\"><code>https:\/\/github.com\/apps\/codecov<\/code><\/a>.\r\n\r\nClick <em>Install &gt; Select your GitHub profile &gt; Only select repositories<\/em>. Select your desired repositories, then click <em>Install<\/em>.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/KRgDNdc.png\" alt=\"Installing Codecov in GitHub\" \/>\r\n\r\nNote that you should choose <em>Only select repositories<\/em> because you want Codecov to be installed only on one repo, rather than all your repos on Github.\r\n\r\nWith your selections made, you will see a <em>Welcome to Codecov<\/em> message. To access your Codecov dashboard, click the <em>Login with GitHub<\/em> icon.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/Hy80rGF.png\" alt=\"Welcome to Codecov\" \/>\r\n\r\nClick <em>Add repository<\/em> to see a list of your repos. Select the repo whose code you want covered. Note that when using GitHub Actions with Codecov, you\u2019ll need a unique upload token only if your repo is private. The token is required to identify which project the coverage belongs to.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/XhSWD9s.png\" alt=\"A unique upload token\" \/>\r\n\r\nBefore pushing your code coverage report to Codecov, take note of the report formats Codecov supports:\r\n<ul>\r\n \t<li>.xml (Cobertura XML, JaCoCo XML, etc.)<\/li>\r\n \t<li>.json (Erlang JSON, Elm JSON, etc.)<\/li>\r\n \t<li>.txt (LCOV, Gcov, Golang)<\/li>\r\n<\/ul>\r\nFor this tutorial, you\u2019ll need the JaCoCo XML report format.\r\n\r\nTo automate the process of sending your code coverage report to Codecov, follow these steps:\r\n<ol>\r\n \t<li>Add a YAML file in the root of your project. The name of the file and extension should be <code>codecov.yml<\/code>.<\/li>\r\n<\/ol>\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/motxGBr.png\" alt=\"The codecov .yml file\" \/>\r\n<ol>\r\n \t<li>Add the following workflow in your GitHub action .yml file. Note that where you see <code>CodeCoverage_Example<\/code>, replace it with your project name.<\/li>\r\n<\/ol>\r\n<pre><code>{\r\n <span class=\"hljs-attr\">\"fixes\"<\/span>: [\r\n <span class=\"hljs-string\">\"\/home\/runner\/work\/CodeCoverage_Example\/CodeCoverage_Example&gt;\/::\"<\/span>\r\n ],\r\n <span class=\"hljs-attr\">\"codecov\"<\/span>: {\r\n <span class=\"hljs-attr\">\"disable_default_path_fixes\"<\/span>: <span class=\"hljs-literal\">true<\/span>\r\n }\r\n}\r\n<\/code><\/pre>\r\n<pre><code><span class=\"hljs-attribute\">name<\/span>: CI\r\n\r\n<span class=\"less\"># <span class=\"hljs-selector-tag\">Controls<\/span> <span class=\"hljs-keyword\">when<\/span> the action will run. \r\n<span class=\"hljs-attribute\">on<\/span>:\r\n # Triggers the workflow on push or pull request events but only for the master branch\r\n <span class=\"hljs-attribute\">push<\/span>:\r\n <span class=\"hljs-attribute\">branches<\/span>: [ master ]\r\n <span class=\"hljs-attribute\">pull_request<\/span>:\r\n <span class=\"hljs-attribute\">branches<\/span>: [ master ]\r\n\r\n# A workflow run is made up of one or more jobs that can run sequentially or in parallel\r\n<span class=\"hljs-attribute\">jobs<\/span>:\r\n # This workflow contains a single job called <span class=\"hljs-string\">\"build\"<\/span>\r\n <span class=\"hljs-attribute\">build<\/span>:\r\n # The type of runner that the job will run on\r\n <span class=\"hljs-attribute\">runs-on<\/span>: macos-latest\r\n\r\n # Steps represent a sequence of tasks that will be executed as part of the job\r\n <span class=\"hljs-attribute\">steps<\/span>:\r\n # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it\r\n - <span class=\"hljs-attribute\">uses<\/span>: actions\/checkout<span class=\"hljs-variable\">@v2<\/span>\r\n\r\n # Execute unit tests\r\n - <span class=\"hljs-attribute\">name<\/span>: Unit Test with Android Emulator Runner\r\n <span class=\"hljs-attribute\">uses<\/span>: ReactiveCircus\/android-emulator-runner<span class=\"hljs-variable\">@v2<\/span>.<span class=\"hljs-number\">14.3<\/span>\r\n <span class=\"hljs-attribute\">with<\/span>: \r\n <span class=\"hljs-attribute\">api-level<\/span>: <span class=\"hljs-number\">29<\/span>\r\n <span class=\"hljs-attribute\">script<\/span>: .\/gradlew connectedCheck \r\n\r\n # <span class=\"hljs-attribute\">run<\/span>: .\/gradlew testDebugUnitTest\r\n\r\n - <span class=\"hljs-attribute\">name<\/span>: generate report\r\n <span class=\"hljs-attribute\">uses<\/span>: actions\/upload-artifact<span class=\"hljs-variable\">@v2<\/span>\r\n <span class=\"hljs-attribute\">with<\/span>:\r\n <span class=\"hljs-attribute\">name<\/span>: report \r\n <span class=\"hljs-attribute\">path<\/span>: app\/build\/reports\/coverage\/debug\r\n\r\n\r\n - <span class=\"hljs-attribute\">name<\/span>: Download Test Reports Folder\r\n <span class=\"hljs-attribute\">uses<\/span>: actions\/download-artifact<span class=\"hljs-variable\">@v2<\/span>\r\n <span class=\"hljs-attribute\">with<\/span>:\r\n <span class=\"hljs-attribute\">name<\/span>: report\r\n <span class=\"hljs-attribute\">path<\/span>: app\/build\/reports\/coverage\/debug\r\n\r\n - <span class=\"hljs-attribute\">name<\/span>: Upload Test Report\r\n uses: codecov\/codecov-action@v2\r\n with:\r\n files: <span class=\"hljs-comment\">\"app\/build\/reports\/coverage\/debug\/report.xml\"<\/span><\/span>\r\n<\/code><\/pre>\r\nYou can now commit your changes and wait for your build to finish. If the build is successful, you\u2019ll see a green checkmark beside the commit name, and red if it\u2019s not successful.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/efVId9V.png\" alt=\"All workflow runs\" \/>\r\n\r\nClick <em>Update codecoverage.yml<\/em> to see the workflow.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/v7RCmjU.png\" alt=\"GitHub Actions build\" \/>\r\n\r\nClick <em>build<\/em> to see the logs.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/5uX8LMB.png\" alt=\"Build succeeded\" \/>\r\n\r\nClick <em>Upload Test Report<\/em> to see the code coverage upload to Codecov logs.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/Qu5NAJ3.png\" alt=\"A code coverage workflow\" \/>\r\n\r\nOn the bottom of the screen, click the URL after <em>View report at:<\/em> to be able to see your code coverage on the Codecov platform.\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/71yYAJd.png\" alt=\"Code coverage logs\" \/>\r\n\r\n<img src=\"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/02\/we4bEle.png\" alt=\"A report on the Codecov platform\" \/>\r\n<h2 id=\"conclusion\">Conclusion<\/h2>\r\nCode coverage is the measurement of how much of your source code your tests actually touch. In Android development, you can generate test coverage reports locally using JaCoCo, and then remotely store them using Codecov.\r\n\r\nYou can automate the process of generating and sending your code coverage to any code coverage storage platform. <a href=\"https:\/\/about.codecov.io\/\">Codecov<\/a> makes it easy to send your code coverage, supports many programming languages and frameworks, supports lots of code coverage report formats, and can be integrated into many CI\/CD platforms, like GitHub Actions and <a href=\"https:\/\/www.bitrise.io\/\">Bitrise<\/a>.","post_title":"Code Coverage for Android Development Using Kotlin, JaCoCo, GitHub Actions, and Codecov","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"code-coverage-for-android-development-using-kotlin-jacoco-github-actions-and-codecov","to_ping":"","pinged":"","post_modified":"2023-01-25 12:02:48","post_modified_gmt":"2023-01-25 17:02:48","post_content_filtered":"","post_parent":0,"guid":"https:\/\/about.codecov.io\/?p=4227","menu_order":0,"post_type":"post","post_mime_type":"","comment_count":"0","filter":"raw","language":[207,63],"tools":[76,230,241,79],"image":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/03032021_Code-Coverage-for-Android-Development-Using-Kotlin-JaCoCo-GitHub-Actions-and-Codecov-scaled.jpg","featured":"https:\/\/about.codecov.io\/wp-content\/uploads\/2022\/08\/03032021_Code-Coverage-for-Android-Development-Using-Kotlin-JaCoCo-GitHub-Actions-and-Codecov-scaled.jpg","codecovLogo":"\/wp-content\/themes\/codecov\/assets\/brand\/icons\/codecov\/codecov-circle.svg","type":"Blog Post","permalink":"https:\/\/about.codecov.io\/blog\/code-coverage-for-android-development-using-kotlin-jacoco-github-actions-and-codecov\/","authorID":"31","authorHeadshot":"https:\/\/about.codecov.io\/wp-content\/uploads\/2021\/03\/wisdom__1_-removebg-preview.png","authorDisplayName":"Wisdom Nwokocha","authorURL":"https:\/\/www.linkedin.com\/in\/wisdom-nwokocha-76212a77\/","cta":"Read Blog Post"}]; </script> <div id="marketecture_diagram"></div> </div> <script src="https://about.codecov.io/wp-content/themes/codecov/vue-components/diagram/dist/js/build.js?version=1742396676"></script> </div> </section> </main> <footer id="footer"> <!-- BOTTOM FOOTER --> <div id="footer__bottom"> <div class="container"> <div class="row d-flex justify-content-center"> <div class="col-12 col-lg-10 d-flex justify-content-center text-center"> <nav> <ul> <li><a href="/terms-of-service/">Terms of Service</a></li> <li><a href="/privacy/">Privacy</a></li> <li><a href="/security/">Security</a></li> <li><a href="/gdpr/">GDPR</a></li> <li><a href="/data-processing-addendum/">Data Processing Addendum</a></li> <li><a href="#" class="cky-banner-element">Cookie Preferences</a></li> <li><a href="/privacy/#tabs--california">California Privacy Notice</a></li> </ul> </nav> </div> <div class="col-12 d-flex justify-content-center align-items-center"> <p>© 2025 • SENTRY IS A REGISTERED TRADEMARK OF FUNCTIONAL SOFTWARE, INC.</p> </div> </div> </div> </div> </footer> <!-- LikeBtn.com BEGIN --> <script type="text/javascript">var likebtn_wl = 1; (function(d, e, s) {a = d.createElement(e);m = d.getElementsByTagName(e)[0];a.async = 1;a.src = s;m.parentNode.insertBefore(a, m)})(document, 'script', '//w.likebtn.com/js/w/widget.js'); if (typeof(LikeBtn) != "undefined") { LikeBtn.init(); }</script> <!-- LikeBtn.com END --> <link rel='stylesheet' id='yarppRelatedCss-css' href='https://about.codecov.io/wp-content/plugins/yet-another-related-posts-plugin/style/related.css?ver=5.30.10' type='text/css' media='all' /> <script type="text/javascript" id="dcl_comments-js-extra"> /* <![CDATA[ */ var countVars = {"disqusShortname":"codecov"}; var embedVars = {"disqusConfig":{"integration":"wordpress 3.0.23"},"disqusIdentifier":"153 https:\/\/about.codecov.io\/product\/integrations\/language\/lua\/","disqusShortname":"codecov","disqusTitle":"Lua","disqusUrl":"https:\/\/about.codecov.io\/language\/lua\/","postId":"153"}; var dclCustomVars = {"dcl_progress_text":"Loading..."}; /* ]]> */ </script> <script type="text/javascript" src="https://about.codecov.io/wp-content/plugins/disqus-conditional-load/assets/js/embed-count-scroll.min.js?ver=11.1.2" id="dcl_comments-js"></script> <script type="text/javascript" src="https://about.codecov.io/wp-content/themes/codecov/assets/scripts/main-lean.js?version=1742396675&amp;ver=6.7.2" id="script-single-language-js"></script> <script type="text/javascript" src="https://about.codecov.io/wp-content/plugins/page-links-to/dist/new-tab.js?ver=3.3.7" id="page-links-to-js"></script> <script type="text/javascript" src="https://about.codecov.io/wp-includes/js/comment-reply.min.js?ver=6.7.2" id="comment-reply-js" async="async" data-wp-strategy="async"></script> <div id="github-login-interstitial"> <div class="row"> <div class="col-12"> <div class="alert alert-info"> <h5>Before we redirect you to GitHub...</h5> <small>In order to use Codecov an admin must approve your org.</small> </div> </div> <div class="col-10 mx-auto my-3"> <img src="/wp-content/themes/codecov/assets/temp/request-access.gif" class="img-fluid" loading="lazy" /> </div> <div class="col-12"> <a class="btn-github-private plausible-event-name=Click+Github" id="github-private" class="btn btn-sm btn-pink float-right d-block" href="https://codecov.io/login/gh">Continue to GitHub &rarr;</a> </div> <div class="col-12 pt-2"> <a class="btn-github-public plausible-event-name=Click+Github" class="float-right d-block" href="https://codecov.io/login/gh"><small>Continue to GitHub (Public Repos Only) &rarr;</small></a> </div> </div> </div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10