<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vikas Yadav</title>
    <description>The latest articles on DEV Community by Vikas Yadav (@vikas1712).</description>
    <link>https://dev.to/vikas1712</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1273839%2F4ca39835-ae98-484d-a0c1-aa5ead3fa59b.JPG</url>
      <title>DEV Community: Vikas Yadav</title>
      <link>https://dev.to/vikas1712</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vikas1712"/>
    <language>en</language>
    <item>
      <title>💡Advance Coding Tips: Object Reuse for Performance Win</title>
      <dc:creator>Vikas Yadav</dc:creator>
      <pubDate>Tue, 08 Apr 2025 09:27:42 +0000</pubDate>
      <link>https://dev.to/vikas1712/advance-coding-tips-object-reuse-for-performance-win-195j</link>
      <guid>https://dev.to/vikas1712/advance-coding-tips-object-reuse-for-performance-win-195j</guid>
      <description>&lt;h2&gt;
  
  
  🎯 TL;DR
&lt;/h2&gt;

&lt;p&gt;If you're allocating memory or creating objects repeatedly inside loops when the data doesn’t change—stop. Build once, reuse, and only clone when needed. This small change can lead to huge gains in performance, especially in high-frequency or large-scale systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 The Principle: Avoid Repeated Allocations
&lt;/h2&gt;

&lt;p&gt;Creating the same object(s) multiple times inside a loop causes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Higher memory usage&lt;/li&gt;
&lt;li&gt;Increased CPU cycles&lt;/li&gt;
&lt;li&gt;More frequent garbage collection (GC)&lt;/li&gt;
&lt;li&gt;Slower performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, build shared data structures once, and reuse or clone them only when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  📜 Real-Life Analogy: The Form Copying Example
&lt;/h2&gt;

&lt;p&gt;Let’s say you’re filling out a form with mostly static data and need 10 copies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Inefficient: You retype the entire form 10 times. Waste of time and energy.&lt;/li&gt;
&lt;li&gt;✅ Efficient: You fill out one master form and photocopy it 10 times. Fast and smart.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly how object creation in loops works in code. The CPU is your typist. Memory is your paper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before vs After: Code Comparison
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10; i++)
{
    var data = new List&amp;lt;string&amp;gt;
    {
        "sensor1",
        "sensor2",
        "sensor3"
    };

    Process(data);
}

- Above code Creates a new list each time.
- Allocates memory 10 times.
- Creates GC pressure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimized Code (Allocate Once, Clone When Needed)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var baseData = new List&amp;lt;string&amp;gt; { "sensor1", "sensor2", "sensor3" };

for (int i = 0; i &amp;lt; 10; i++)
{
    var clonedData = new List&amp;lt;string&amp;gt;(baseData); // shallow copy
    Process(clonedData);
}

- Above Creates the base list once.
- Clones it for each iteration to avoid shared references.
- Saves memory and CPU cycles.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Concept: "Reduce Unnecessary Allocations"
&lt;/h2&gt;

&lt;p&gt;❌ What's the problem?&lt;br&gt;
If you're creating new objects inside a loop that don’t need to change every time, you’re doing unnecessary work. That leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More memory allocations (objects on the heap).&lt;/li&gt;
&lt;li&gt;More garbage collection.&lt;/li&gt;
&lt;li&gt;More CPU cycles wasted rebuilding the same thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ The solution:&lt;br&gt;
Build it once outside the loop if it’s static. Then, clone it inside the loop only if it needs to be modified per call to avoid shared reference issues&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways Points
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"If it doesn't change, don’t build it more than once."&lt;/li&gt;
&lt;li&gt;Use analogies like form photocopying.&lt;/li&gt;
&lt;li&gt;Show side-by-side code examples.&lt;/li&gt;
&lt;li&gt;Explain how repeated allocations lead to higher GC frequency and slower execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧩 Bonus Tip
&lt;/h2&gt;

&lt;p&gt;Even in test code, performance matters—especially when tests run hundreds of times in CI/CD pipelines. Optimizing test code leads to faster pipelines and happier devs.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Setup Code Coverage for Monorepo - SonarQube</title>
      <dc:creator>Vikas Yadav</dc:creator>
      <pubDate>Tue, 23 Apr 2024 08:06:48 +0000</pubDate>
      <link>https://dev.to/vikas1712/setup-code-coverage-for-monorepo-sonarqube-4i69</link>
      <guid>https://dev.to/vikas1712/setup-code-coverage-for-monorepo-sonarqube-4i69</guid>
      <description>&lt;p&gt;In a Monorepo setup, generating a coverage report for each library or app separately is common. &lt;/p&gt;

&lt;p&gt;However, tools like the Sonar scanner may encounter difficulties in combining these reports into a single comprehensive one. &lt;/p&gt;

&lt;p&gt;This issue arises when running tests with tools like nx affected, where only affected projects generate coverage reports, leaving unaffected projects out. &lt;/p&gt;

&lt;p&gt;Consequently, SonarQube may raise quality gate errors due to missing coverage data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5nnox1yflpfc7m245t1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5nnox1yflpfc7m245t1i.png" alt="Project Structure " width="800" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Propose Solution Implemented
&lt;/h2&gt;

&lt;p&gt;To resolve this problem, a custom script can be added to merge coverage reports into one file. &lt;/p&gt;

&lt;p&gt;Below is a simple JavaScript function named &lt;strong&gt;&lt;code&gt;coveragemerger.js&lt;/code&gt;&lt;/strong&gt; for this purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;glob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;glob&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;util&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;util&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REPORTS_DIR_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;coverage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GREEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;x1b[32m%s&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;x1b[0m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BLUE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;x1b[34m%s&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;x1b[0m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REPORTS_DIR_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;REPORTS_DIR_NAME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;promisify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Fetches all lcov.info files from coverage directories, excluding node_modules.
 * @returns {Promise&amp;lt;string[]&amp;gt;} A promise that resolves with an array of file paths.
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLcovFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;globPromise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`**/coverage/lcov.info`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**/node_modules/**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Creates a temp directory for all the reports.
 * @returns {Promise&amp;lt;void&amp;gt;} A promise that resolves when the directory has been created.
 */&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createTempDir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BLUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Creating a temp &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;REPORTS_DIR_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; directory...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;REPORTS_DIR_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GREEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Done!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error creating directory:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fetch all lcov.info files&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getLcovFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;files are&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create temp directory&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createTempDir&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Read all files and join their contents&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mergedReport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BLUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Copying the coverage report...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Write the merged report to a new lcov.info file&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;REPORTS_DIR_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`lcov.info`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;mergedReport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Code coverage has been saved!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Azure Pipeline Integration
&lt;/h2&gt;

&lt;p&gt;To integrate this into your pipeline, add the following command to your Azure Pipeline file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;node coverageMerger.js&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Merge&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Coverage&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Reports'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SonarQube Analysis Report
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhwkvk0gnmh1ligjwa2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhwkvk0gnmh1ligjwa2f.png" alt="SonarQube Analysis - Monorepo" width="706" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reference:&lt;br&gt;
use this site to check coverage from LCOV &lt;a href="https://lcov-viewer.netlify.app/" rel="noopener noreferrer"&gt;https://lcov-viewer.netlify.app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>codecoverage</category>
      <category>sonarqube</category>
      <category>monorepo</category>
    </item>
    <item>
      <title>Introduction to Bruno Scripting</title>
      <dc:creator>Vikas Yadav</dc:creator>
      <pubDate>Sat, 20 Apr 2024 17:46:22 +0000</pubDate>
      <link>https://dev.to/vikas1712/introduction-to-bruno-scripting-5a1n</link>
      <guid>https://dev.to/vikas1712/introduction-to-bruno-scripting-5a1n</guid>
      <description>&lt;p&gt;In the dynamic world of API development and testing, automation is key.&lt;/p&gt;

&lt;p&gt;Bruno offers scripting support to help you add additional functionality to the tool such as data generation, validation, and integration with other tools and systems, including sending intermediate requests, parsing response data, updating environment variables, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secrets Management
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Problem Statement
&lt;/h4&gt;

&lt;p&gt;In any collection, there are secrets that need to be managed. These secrets can be anything such as API keys, passwords, or tokens.&lt;/p&gt;

&lt;p&gt;A common practice is to store these secrets in environment variables.&lt;/p&gt;

&lt;p&gt;There are two ways in which developers share Bruno collections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check in the collection folder to source control (like git)&lt;/li&gt;
&lt;li&gt;Export the collection to a file and share it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both these cases, we want to ensure that the secrets are stripped out of the collection before it is shared.&lt;/p&gt;

&lt;h4&gt;
  
  
  Solution
&lt;/h4&gt;

&lt;p&gt;Bruno offers two approaches to manage secrets in collections:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;DotEnv File&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secret Variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Core Features of Bruno Scripting
&lt;/h2&gt;

&lt;p&gt;Bruno is a scripting framework built to providing advanced functionality and automation capabilities. With Bruno, developers can elevate their API testing and development workflows by enabling tasks such as data generation, validation processes, integration with other tools and systems, and much more.&lt;/p&gt;

&lt;p&gt;Let's explore some of the core features and functionalities that Bruno brings to the table:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Data Generation and Validation
&lt;/h3&gt;

&lt;p&gt;Bruno allows for seamless data generation within the testing environment, enabling developers to simulate various scenarios and edge cases. Furthermore, it facilitates robust validation processes, ensuring that APIs behave as expected under different conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Integration and Interoperability
&lt;/h3&gt;

&lt;p&gt;One of Bruno's strengths lies in its ability to integrate with other tools and systems seamlessly. Whether you're orchestrating complex workflows or incorporating third-party services, Bruno streamlines the process, enhancing collaboration and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Intermediate Requests and Response Parsing
&lt;/h3&gt;

&lt;p&gt;With Bruno, developers can execute intermediate requests within their workflows, enabling sophisticated test scenarios and intricate API interactions. Moreover, Bruno simplifies the parsing of response data, making it easier to extract and manipulate relevant information.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Environment Management
&lt;/h3&gt;

&lt;p&gt;Bruno empowers developers to manage environment variables effortlessly, facilitating configuration management and ensuring consistency across different testing environments. Whether it's updating variables or accessing environment-specific data, Bruno simplifies the process, enhancing workflow efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Translating Postman Scripts to Bruno Commands
&lt;/h2&gt;

&lt;p&gt;To illustrate Bruno's capabilities further, let's translate some common Postman scripts into Bruno commands:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Bruno Command&lt;/th&gt;
&lt;th&gt;Postman Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tests confirm API is working&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bru.test("check status code", function() { expect(res.status).to.equal(200); });&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pm.test("check status code", function() { pm.response.to.have.status(200); });&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set Collection Variable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bru.setVar("auth_token", res.body.userid);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pm.collectionVariables.set("auth_token", "abc123");&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get Collection Variable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bru.getVar("auth_token");&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pm.collectionVariables.get("auth_token");&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set Environment Variable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bru.setEnvVar("api_key", "xyz1712");&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pm.environment.set("api_key", "xyz1712");&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get Environment Variable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bru.getEnvVar("api_key");&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pm.environment.get("api_key");&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Order Next Request&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bru.setNextRequest("Token_SSO");&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pm.setNextRequest("Token_rock");&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In conclusion, Bruno enables advanced automation, customization, and flexibility, helping developers deliver high-quality APIs with confidence.&lt;/p&gt;

&lt;p&gt;Bruno supports loading any npm module to use in your scripting workflows.&lt;/p&gt;

&lt;p&gt;You need to add a &lt;code&gt;package.json&lt;/code&gt; file where your collection is stored.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
json
{
  "name": "bruno_api_demo",
  "version": "1.0.0",
  "description": "With Bruno CLI, you can now run your API collections with ease using simple command line commands.",
  "author": "vikas.yadav",
  "license": "ISC",
  "keywords": [
    "bruno",
    "api testing"
  ],
  "scripts": {
    "test": "bru run Oauth-Login --env test_vikas --format junit --output results.xml"
  },
  "dependencies": {
    "@usebruno/cli": "~1.11.0",
    "@faker-js/faker": "8.3.1"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>testing</category>
      <category>postman</category>
      <category>bruno</category>
      <category>apitesting</category>
    </item>
    <item>
      <title>Bruno: Secure API Testing Solution</title>
      <dc:creator>Vikas Yadav</dc:creator>
      <pubDate>Thu, 11 Apr 2024 13:27:49 +0000</pubDate>
      <link>https://dev.to/vikas1712/bruno-secure-api-testing-solution-2f9i</link>
      <guid>https://dev.to/vikas1712/bruno-secure-api-testing-solution-2f9i</guid>
      <description>&lt;h2&gt;
  
  
  Bruno: A Secure and User-Friendly Alternative for Postman
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.usebruno.com/" rel="noopener noreferrer"&gt;Bruno&lt;/a&gt; is a new and innovative API client, designed to challenge the status quo represented by Postman and similar tools. &lt;/p&gt;

&lt;p&gt;Bruno's unique approach involves storing your collections directly on your filesystem. We utilize a plain text markup language, Bru, to save information about API requests. This means you have full control over your data and can easily track changes.&lt;/p&gt;

&lt;p&gt;Moreover, Bruno's design allows you to use Git or any version control system of your choice to collaborate on your API collections. This makes Bruno not just an API testing tool, but a platform for efficient and effective team collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Switch from Postman and Insomnia?
&lt;/h2&gt;

&lt;p&gt;In the world of API testing, Postman and Insomnia have been popular choices. However, recent changes have raised concerns about data security and offline functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postman&lt;/strong&gt; announced in May 2023 that it would gradually phase out its Scratch Pad model with offline capabilities. Most functions will now require cloud access and user login. The extent of data upload to the cloud during testing, potentially compromising security, remains uncertain.&lt;br&gt;
&lt;a href="https://www.leeholmes.com/security-risks-of-postman/#:~:text=Postman%27s%20Security%20Risk,was%20the%20on-premises%20application" rel="noopener noreferrer"&gt;Read more here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Insomnia&lt;/strong&gt; released version 8.0 on September 28, 2023, intensifying its reliance on the cloud. Full functionality now requires user login, and Scratch Pad features are limited without it. The security implications of potential data transmission to the cloud during testing are unclear.&lt;/p&gt;

&lt;p&gt;Given these changes, there's a growing need for an API testing solution that keeps workspace data isolated from third-party servers. Enter Bruno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Bruno?
&lt;/h2&gt;

&lt;p&gt;Bruno offers a secure, user-friendly alternative for your API testing needs. Here's why you should consider making the switch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Source&lt;/strong&gt;: Bruno is open-source software under the MIT License, fostering a collaborative and transparent development environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-Platform Support&lt;/strong&gt;: Bruno supports Mac, Linux, and Windows, making it a versatile choice for diverse teams.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Offline Client&lt;/strong&gt;: Unlike its competitors, Bruno has no plans for cloud synchronization, prioritizing your data security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Script Import&lt;/strong&gt;: Bruno supports script import from Postman and Insomnia (limited to API request scripts, excluding test scripts), easing the transition process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Active Community&lt;/strong&gt;: Bruno boasts a relatively active community and a clear product development roadmap, ensuring continuous improvement and support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Seamless Transition with Bruno
&lt;/h2&gt;

&lt;p&gt;One of the standout features of Bruno is its ability to import existing collections from various tools. This means you can easily transition your API testing workflow without starting from scratch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Postman Collections&lt;/strong&gt;: Bruno supports the import of Postman collections. This allows you to bring in all your saved API requests, maintaining the organization and structure you're familiar with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Insomnia Collections&lt;/strong&gt;: If you're coming from Insomnia, Bruno has you covered. You can import your Insomnia collections, ensuring your API testing continues smoothly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OpenAPI v3 Spec&lt;/strong&gt;: Bruno also supports the import of OpenAPI v3 specifications. This means you can leverage your existing API design and documentation, making Bruno a versatile choice for API testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This import functionality makes Bruno a flexible tool that adapts to your needs, reducing the friction typically associated with switching to a new API testing platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnan9n58x0eulwnduviw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnan9n58x0eulwnduviw6.png" alt="Image description" width="535" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs996ssjxxbyvavj128bz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs996ssjxxbyvavj128bz.png" alt="Image description" width="595" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information, check out the &lt;a href="https://github.com/usebruno/bruno/discussions/269" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; and the &lt;a href="https://www.usebruno.com/compare/bruno-vs-postman" rel="noopener noreferrer"&gt;comparison with Postman&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>bruno</category>
      <category>api</category>
      <category>postman</category>
    </item>
  </channel>
</rss>
