<?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>Forem: mhossen</title>
    <description>The latest articles on Forem by mhossen (@mhossen).</description>
    <link>https://forem.com/mhossen</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%2F194450%2F1931c05e-d82f-4372-92a3-e54af1d9a57a.png</url>
      <title>Forem: mhossen</title>
      <link>https://forem.com/mhossen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mhossen"/>
    <language>en</language>
    <item>
      <title>FizzBuzz: if…else if vs continue (and why order matters)</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Sun, 24 Aug 2025 17:47:09 +0000</pubDate>
      <link>https://forem.com/mhossen/fizzbuzz-ifelse-if-vs-continue-and-why-order-matters-3e9g</link>
      <guid>https://forem.com/mhossen/fizzbuzz-ifelse-if-vs-continue-and-why-order-matters-3e9g</guid>
      <description>&lt;p&gt;FizzBuzz is one of the first exercises many developers learn. The rules are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Print numbers from 1 to 100&lt;/li&gt;
&lt;li&gt;If the number is divisible by 3, print “Fizz”&lt;/li&gt;
&lt;li&gt;If the number is divisible by 5, print “Buzz”&lt;/li&gt;
&lt;li&gt;If the number is divisible by both 3 and 5, print “FizzBuzz”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It looks straightforward, but the way you structure the conditions makes a difference. Let’s look at two approaches: using if...else if and using continue.&lt;/p&gt;




&lt;p&gt;What does divisible really mean?&lt;/p&gt;

&lt;p&gt;When we say “divisible,” we mean the number divides evenly without leaving a remainder. In C#, we use the modulo operator % to check for remainders.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;   &lt;span class="c1"&gt;// true, because 6 divided by 3 has no remainder&lt;/span&gt;
&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;// true, because 10 divided by 5 has no remainder&lt;/span&gt;
&lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;   &lt;span class="c1"&gt;// false, remainder is 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So when you see if (i % 3 == 0), it means “if the number can be divided by 3 with no remainder.”&lt;/p&gt;




&lt;p&gt;The if…else if approach&lt;/p&gt;

&lt;p&gt;The most common way is to chain conditions together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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;p&gt;Here, the else if structure ensures that only one condition runs for each number.&lt;/p&gt;

&lt;p&gt;Why check for both first?&lt;/p&gt;

&lt;p&gt;If we wrote the code like this instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then a number like 15 would match the first condition (i % 3 == 0) and stop there. It would print “Fizz” and never reach “FizzBuzz.” That is why we check for the most specific condition first.&lt;/p&gt;

&lt;p&gt;Think of it like a decision tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the number divisible by 3 and 5 (no remainder)?
   Yes -&amp;gt; FizzBuzz
   No -&amp;gt;
      Is it divisible by 3 (no remainder)?
         Yes -&amp;gt; Fizz
         No -&amp;gt;
            Is it divisible by 5 (no remainder)?
               Yes -&amp;gt; Buzz
               No -&amp;gt; Just print the number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;The continue approach&lt;/p&gt;

&lt;p&gt;Another way is to write each condition separately and use continue to move on to the next number once a match is found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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;p&gt;In this version, each condition is independent. Once one is true, the continue keyword skips the rest and goes straight to the next loop iteration.&lt;/p&gt;




&lt;p&gt;Which style is better?&lt;/p&gt;

&lt;p&gt;Both approaches work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if...else if is a bit cleaner when conditions are mutually exclusive.&lt;/li&gt;
&lt;li&gt;continue keeps conditions separate and avoids nesting, but it does require a little more repetition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For something as small as FizzBuzz, it comes down to personal preference. What matters most is making sure the conditions are in the right order.&lt;/p&gt;




&lt;p&gt;Final thought&lt;/p&gt;

&lt;p&gt;When I first tried &lt;code&gt;FizzBuzz&lt;/code&gt;, I made the mistake of checking &lt;code&gt;i % 3 == 0&lt;/code&gt; before checking for both 3 and 5. As a result, &lt;code&gt;“FizzBuzz”&lt;/code&gt; never printed. That small mistake taught me the importance of writing conditions in the right order.&lt;/p&gt;

&lt;p&gt;And always remember: divisible means there should be no remainder.&lt;/p&gt;

&lt;p&gt;No matter which style you use, always check the most specific case first.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>beginners</category>
      <category>coding</category>
    </item>
    <item>
      <title>Rethinking the Test Pyramid: A Balanced View from Code to Customer</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Tue, 12 Aug 2025 22:43:24 +0000</pubDate>
      <link>https://forem.com/mhossen/rethinking-the-test-pyramid-a-balanced-view-from-code-to-customer-5bhl</link>
      <guid>https://forem.com/mhossen/rethinking-the-test-pyramid-a-balanced-view-from-code-to-customer-5bhl</guid>
      <description>&lt;p&gt;When we talk about automated testing, the &lt;strong&gt;Test Pyramid&lt;/strong&gt; often comes up. This is a popular model introduced by Mike Cohn. While it provides a solid foundation for designing test strategies in software development, it is time we evolve the conversation.&lt;/p&gt;

&lt;p&gt;When we factor in real-world business impact and modern testing tools, the classic pyramid starts to look a bit too one-dimensional.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧱 The Classic Test Pyramid (Mike Cohn)
&lt;/h2&gt;

&lt;p&gt;The original Test Pyramid encourages teams to write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Many&lt;/strong&gt; fast, isolated &lt;strong&gt;unit tests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;Some&lt;/strong&gt; mid-level &lt;strong&gt;integration tests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔺 &lt;strong&gt;Few&lt;/strong&gt; slow and brittle &lt;strong&gt;UI/end-to-end tests&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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%2F7y0mtbm9hdbuol9gw8od.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%2F7y0mtbm9hdbuol9gw8od.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is that unit tests offer the fastest feedback loop, and E2E tests should be used sparingly to keep CI pipelines efficient.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 But What About Business Perspective?
&lt;/h2&gt;

&lt;p&gt;While the traditional pyramid optimizes for &lt;strong&gt;engineering speed and cost&lt;/strong&gt;, it does not always align with what really matters to the &lt;strong&gt;business or the end user&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From that angle, things flip.&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%2Ftsgbiescxyrdese9qq62.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%2Ftsgbiescxyrdese9qq62.png" alt="Inverted Test Pyramid" width="424" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;While unit tests help reduce technical risk, they do not fully answer the business's biggest question: Can users actually complete key workflows like registering, shopping, or submitting a claim without issues? That is where end-to-end testing really delivers confidence.&lt;/p&gt;

&lt;p&gt;Integration tests also play an important role by verifying how components work together. However, because they often rely on mocked dependencies, they do not always reflect real-world scenarios. They help reduce systemic risk but still stop short of validating complete user workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔀 E2E Is Not Just “UI Testing”
&lt;/h2&gt;

&lt;p&gt;Another common misconception is that &lt;strong&gt;E2E means just clicking through the UI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is only part of the picture. A well-designed E2E test should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;APIs to create test data&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Interact with the &lt;strong&gt;UI to simulate real user flows&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Verify &lt;strong&gt;backend changes&lt;/strong&gt; through DB or API assertions&lt;/li&gt;
&lt;li&gt;Perform &lt;strong&gt;efficient cleanup&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Validate &lt;strong&gt;business rules&lt;/strong&gt;, not just user interface elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Modern E2E tests are hybrid by design.&lt;/strong&gt; They use the &lt;strong&gt;right tool for each layer&lt;/strong&gt; while focusing on validating real user value.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Example: Placing an Order
&lt;/h2&gt;

&lt;p&gt;Instead of bloated UI-only flows, consider this smarter E2E approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Precondition&lt;/strong&gt;: Seed test user and product catalog via API
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI Flow&lt;/strong&gt;: Login and checkout using Playwright or Selenium
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assertions&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;UI shows confirmation
&lt;/li&gt;
&lt;li&gt;Database contains the new order
&lt;/li&gt;
&lt;li&gt;API returns the correct order status
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teardown&lt;/strong&gt;: Delete or reset test data using an API call&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is still an end-to-end test, but it is &lt;strong&gt;faster, cleaner, and more reliable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚖️ The Balanced Approach: Engineering and Business Confidence
&lt;/h2&gt;

&lt;p&gt;We do not have to choose one pyramid over the other. Instead, we can &lt;strong&gt;layer them together&lt;/strong&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%2Fe8l5nxdphrk1k8kml9an.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%2Fe8l5nxdphrk1k8kml9an.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fast development feedback&lt;/td&gt;
&lt;td&gt;Unit and service-level tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regression protection&lt;/td&gt;
&lt;td&gt;Integration and smoke tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business confidence&lt;/td&gt;
&lt;td&gt;High-value E2E tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User-centered quality&lt;/td&gt;
&lt;td&gt;Simulated real-world workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚀 Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Test Pyramid still holds value&lt;/strong&gt;, especially for speed and scalability in engineering.&lt;/li&gt;
&lt;li&gt;But do not ignore the &lt;strong&gt;inverted business view&lt;/strong&gt;, where &lt;strong&gt;E2E tests bring the most confidence&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;And please, &lt;strong&gt;do not treat E2E as just UI automation&lt;/strong&gt;. Great E2E tests combine &lt;strong&gt;API, database, and UI validation&lt;/strong&gt; to provide robust, focused proof that your system works where it matters most.&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;Quality is not just about passing unit tests. It is about proving that your system works where it matters most: &lt;strong&gt;in the hands of your users&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>testing</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Java Clean Code Tip for Testers: Use try-with-resources Like a Pro</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Tue, 03 Jun 2025 20:32:25 +0000</pubDate>
      <link>https://forem.com/mhossen/java-clean-code-tip-for-testers-use-try-with-resources-like-a-pro-399j</link>
      <guid>https://forem.com/mhossen/java-clean-code-tip-for-testers-use-try-with-resources-like-a-pro-399j</guid>
      <description>&lt;p&gt;When writing Java tests—be it for automation, backend validation, or reading test data—you'll often deal with resources like files, streams, or database connections. Managing these resources properly is crucial to prevent issues like memory leaks or file locks.&lt;/p&gt;

&lt;p&gt;Let's explore how &lt;code&gt;try-with-resources&lt;/code&gt;, introduced in Java 7, can help you write cleaner and safer code.&lt;/p&gt;




&lt;h2&gt;
  
  
  😬 The Traditional Way (Before Java 7)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;BufferedReader&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.csv"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readLine&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// process line&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is verbose and error-prone. Forgetting to close resources can lead to resource leaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ The Modern Way: try-with-resources
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BufferedReader&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.csv"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lines&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading file: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;try-with-resources&lt;/code&gt;, Java automatically closes the resource at the end of the statement, even if exceptions occur. This leads to cleaner and more reliable code.&lt;/p&gt;




&lt;h2&gt;
  
  
  👩‍💻 Why Testers Should Care
&lt;/h2&gt;

&lt;p&gt;As a tester, you might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read test data from files&lt;/li&gt;
&lt;li&gt;Write logs during test execution&lt;/li&gt;
&lt;li&gt;Interact with databases&lt;/li&gt;
&lt;li&gt;Handle input/output streams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using &lt;code&gt;try-with-resources&lt;/code&gt; ensures that these resources are properly closed, reducing the risk of resource leaks and making your tests more robust.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Real-World Example: Logging in Tests
&lt;/h2&gt;

&lt;p&gt;Here's a utility class to write logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.BufferedWriter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.FileWriter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestLogger&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;writeLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BufferedWriter&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedWriter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileWriter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newLine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not write log: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage in a test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testUserLogin&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;TestLogger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login test started"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"logs/test-log.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// perform test steps&lt;/span&gt;
    &lt;span class="nc"&gt;TestLogger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login test passed"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"logs/test-log.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach ensures that the &lt;code&gt;BufferedWriter&lt;/code&gt; is closed properly after writing, even if an exception occurs.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Handling Multiple Resources
&lt;/h2&gt;

&lt;p&gt;You can manage multiple resources in a single &lt;code&gt;try-with-resources&lt;/code&gt; statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;InputStream&lt;/span&gt; &lt;span class="n"&gt;inStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;OutputStream&lt;/span&gt; &lt;span class="n"&gt;outStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileOutputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.txt"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inStream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;outStream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resources are closed in the reverse order of their declaration.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;try-with-resources&lt;/code&gt; for any resource that implements &lt;code&gt;AutoCloseable&lt;/code&gt; (e.g., files, streams, database connections).&lt;/li&gt;
&lt;li&gt;It simplifies your code and improves test reliability.&lt;/li&gt;
&lt;li&gt;Cleaner code leads to fewer bugs and better maintenance. 🧼&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>java</category>
      <category>testing</category>
      <category>cleancode</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What I Learned in a Decade of Experience in Test Automation</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Wed, 01 Jan 2025 07:54:38 +0000</pubDate>
      <link>https://forem.com/mhossen/what-i-learned-in-a-decade-of-experience-in-test-automation-521i</link>
      <guid>https://forem.com/mhossen/what-i-learned-in-a-decade-of-experience-in-test-automation-521i</guid>
      <description>&lt;p&gt;Let’s start with the big question that many people ask: &lt;strong&gt;which programming language should you choose for automation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everyone seems to have a favorite. Whether it’s JavaScript, Python, Java, or C#, people often swear by the language that has worked best for them. But here’s the truth: all programming languages have the same foundational principles. They differ in syntax, libraries, and how they handle certain tasks, but the building blocks remain the same.&lt;/p&gt;

&lt;p&gt;That said, some languages are undeniably better suited for certain tasks. Some execute faster, others are easier to set up, and some are more beginner-friendly. My advice? &lt;strong&gt;Pick one language and focus on mastering it.&lt;/strong&gt; Don’t try to learn too many languages at once—it’s better to go deep than wide, especially early in your journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Programming Languages Compare in Test Automation
&lt;/h3&gt;

&lt;p&gt;The language you choose can impact the speed and ease of your test automation efforts. Here’s a simplified comparison of some popular languages for key testing criteria:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Ease of Use&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cross-Platform Compatibility&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Database Testing&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;UI Testing&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;API Testing&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy to learn, extensive libraries&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate, verbose syntax&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy, single language for web&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate, great IDE support&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ruby&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy, readable syntax&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Don’t Chase Shiny Objects
&lt;/h3&gt;

&lt;p&gt;One of my favorite quotes is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We are always chasing shiny objects.”&lt;br&gt;&lt;br&gt;
— Tim Corey&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s tempting to switch to the latest language or framework whenever something doesn’t go as planned. But no language or tool is perfect. When you hit a roadblock—like a feature that isn’t supported or something that doesn’t work the way you expect—try to find a solution instead of jumping ship. The software industry thrives on problem-solving, and switching languages at every obstacle would make progress impossible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping It Up
&lt;/h3&gt;

&lt;p&gt;Test automation is about more than just tools and languages—it’s about solving problems. By mastering one language and learning the ins and outs of its frameworks, you’ll be equipped to handle most challenges that come your way. As you gain experience, you’ll be able to adopt new tools and languages with confidence, not because they’re trendy, but because they truly meet your needs.&lt;/p&gt;

</description>
      <category>qa</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Test Automation Best Practices</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Sun, 22 Dec 2024 16:16:02 +0000</pubDate>
      <link>https://forem.com/mhossen/test-automation-best-practices-5ebh</link>
      <guid>https://forem.com/mhossen/test-automation-best-practices-5ebh</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Best Practices for Test Automation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Test automation is a critical strategy for efficiently managing the testing of large, complex systems. It helps establish a standardized process that minimizes human effort and ensures consistent quality across business and product offerings. When implemented correctly, automation provides stakeholders with confidence, freeing up Quality Assurance (QA) Engineers and Analysts to focus on high-value tasks such as exploratory testing. This approach enhances the overall quality of products and services delivered to consumers and clients.&lt;/p&gt;




&lt;h2&gt;
  
  
  Considerations Before Diving into Automation
&lt;/h2&gt;

&lt;p&gt;Before embarking on your automation journey, address the following key questions to ensure alignment with your business and technical goals:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Why Pursue Automation Efforts?
&lt;/h3&gt;

&lt;p&gt;Understanding the core reasons behind automating your tests ensures that your efforts are purposeful. These reasons might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Increasing test coverage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improving test speed and efficiency&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhancing the reliability of repeated tests&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By identifying the "why," you can shape a strategy that solves real problems rather than adopting automation for the sake of trends.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. What Business or Use Cases Justify Automation?
&lt;/h3&gt;

&lt;p&gt;Evaluate if automation is genuinely needed or if manual testing suffices. Key indicators include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High volume of repetitive tests&lt;/strong&gt; (e.g., regression or smoke tests)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frequent changes to critical features&lt;/strong&gt; that require validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability needs&lt;/strong&gt; that manual testing cannot address efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. How Will Automation Be Implemented?
&lt;/h3&gt;

&lt;p&gt;Selecting the right implementation approach is critical. Common options include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UI-Only Automation&lt;/strong&gt;: Ideal for front-end testing but fragile with UI changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-Only Automation&lt;/strong&gt;: Stable and faster, suited for testing business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Automation&lt;/strong&gt;: Verifies data integrity across systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive Automation&lt;/strong&gt;: Combines UI, API, and database testing for thorough coverage&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Questions for Test Automation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Automate?
&lt;/h3&gt;

&lt;p&gt;Test automation offers several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Increase Efficiency&lt;/strong&gt;: Automate repetitive tasks to speed up testing and feedback loops&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve Consistency&lt;/strong&gt;: Eliminate human error with reliable execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhance Test Coverage&lt;/strong&gt;: Run a wider variety of tests more frequently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale Testing&lt;/strong&gt;: Execute tests in parallel across multiple environments or browsers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free Up Resources&lt;/strong&gt;: Allow QA teams to focus on strategic, exploratory testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What to Automate?
&lt;/h3&gt;

&lt;p&gt;Identify areas where automation will have the most impact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High-Priority, Repetitive Tests&lt;/strong&gt;: Ideal for regression and smoke tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-Consuming Tasks&lt;/strong&gt;: Nightly builds or extensive regression tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-Risk Features&lt;/strong&gt;: Critical features frequently updated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance and Load Testing&lt;/strong&gt;: Simulate high user loads efficiently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data-Driven Testing&lt;/strong&gt;: Validate multiple input scenarios and edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Implement Automation?
&lt;/h3&gt;

&lt;p&gt;Follow these steps to create a robust automation strategy:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Define Clear Goals
&lt;/h4&gt;

&lt;p&gt;Establish objectives such as improving test coverage, reducing testing time, or enabling frequent releases.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Choose the Right Tools
&lt;/h4&gt;

&lt;p&gt;Select tools based on your tech stack and team expertise. Popular tools across programming languages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web Testing&lt;/strong&gt;: Selenium, Playwright, Cypress&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Testing&lt;/strong&gt;: Postman, RestAssured, Karate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile Testing&lt;/strong&gt;: Appium, Espresso, XCUITest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit/Integration Testing&lt;/strong&gt;: JUnit, NUnit, PyTest, Mocha&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD&lt;/strong&gt;: Jenkins, GitHub Actions, GitLab CI/CD, Azure DevOps&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Design a Robust Test Framework
&lt;/h4&gt;

&lt;p&gt;Leverage design patterns like Page Object Model or Data-Driven Testing to create modular, reusable, and maintainable scripts.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Integrate with CI/CD Pipelines
&lt;/h4&gt;

&lt;p&gt;Automate tests within your Continuous Integration/Continuous Deployment pipeline to ensure tests run automatically on code changes, enabling rapid feedback.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Monitor and Report
&lt;/h4&gt;

&lt;p&gt;Use reporting tools to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track test results&lt;/li&gt;
&lt;li&gt;Monitor trends over time&lt;/li&gt;
&lt;li&gt;Identify unstable tests&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Implementing test automation requires a thoughtful approach to ensure it addresses real challenges and provides tangible benefits. By defining clear objectives, selecting the right tools, and adopting a robust framework, your team can achieve efficiency, reliability, and scalability in your testing process. Start small, iterate, and watch your testing efforts transform your development lifecycle.&lt;/p&gt;

</description>
      <category>qa</category>
      <category>discuss</category>
      <category>testing</category>
      <category>automation</category>
    </item>
    <item>
      <title>Understanding Superclass vs. Request Decorator: Differences, Benefits, and Use Cases</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Mon, 16 Dec 2024 00:13:16 +0000</pubDate>
      <link>https://forem.com/mhossen/understanding-superclass-vs-request-decorator-differences-benefits-and-use-cases-2ib6</link>
      <guid>https://forem.com/mhossen/understanding-superclass-vs-request-decorator-differences-benefits-and-use-cases-2ib6</guid>
      <description>&lt;p&gt;When working with object-oriented programming in Java, two commonly used patterns are &lt;strong&gt;superclasses&lt;/strong&gt; and &lt;strong&gt;decorator patterns&lt;/strong&gt;. Both promote code reuse but serve different purposes. In this article, we'll explore the differences, benefits, and use cases of using a &lt;strong&gt;decorator&lt;/strong&gt; with a familiar example: an &lt;code&gt;Animal&lt;/code&gt; class.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What is a Superclass?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;superclass&lt;/strong&gt; is a base class that provides common attributes and behaviors for its derived classes (subclasses). The relationship is built using inheritance, where subclasses share or extend the functionality defined by the superclass.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key Traits of a Superclass&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inheritance-based:&lt;/strong&gt; Subclasses inherit attributes and behaviors directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared behavior:&lt;/strong&gt; Encapsulates logic common to all derived classes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static relationship:&lt;/strong&gt; The structure is determined at compile-time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example: Using Animal as a Superclass&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;eat&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This animal eats food."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;bark&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The dog barks."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SuperclassExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;eat&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Inherited from Animal&lt;/span&gt;
        &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bark&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Specific to Dog&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Animal&lt;/code&gt; is the superclass.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Dog&lt;/code&gt; inherits the &lt;code&gt;eat&lt;/code&gt; behavior and adds its own functionality.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What is a Decorator?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Decorator Pattern&lt;/strong&gt; is a structural design pattern that dynamically adds new functionality to an object at runtime without altering its structure. It relies on &lt;strong&gt;composition&lt;/strong&gt; rather than inheritance.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key Traits of a Decorator&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Composition-based:&lt;/strong&gt; Wraps objects to extend or modify their behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic behavior:&lt;/strong&gt; Adds functionality at runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensibility-friendly:&lt;/strong&gt; Aligns with the Open/Closed Principle by allowing functionality extension without modifying existing code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Example: Using Animal with a Decorator&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Suppose you want to dynamically add new behaviors (like making the animal "fly" or "swim") to an existing &lt;code&gt;Animal&lt;/code&gt; object without creating a new subclass for each behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Decorator Implementation&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicAnimal&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This animal makes a sound."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FlyingAnimalDecorator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FlyingAnimalDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"It can also fly!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SwimmingAnimalDecorator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;SwimmingAnimalDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"It can also swim!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DecoratorExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;basicAnimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BasicAnimal&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Adding flying behavior&lt;/span&gt;
        &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;flyingAnimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FlyingAnimalDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicAnimal&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;flyingAnimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Adding swimming behavior&lt;/span&gt;
        &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;swimmingAnimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SwimmingAnimalDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicAnimal&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;swimmingAnimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Combining behaviors&lt;/span&gt;
        &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;flyingSwimmingAnimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SwimmingAnimalDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flyingAnimal&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;flyingSwimmingAnimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeSound&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Output&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This animal makes a sound.
It can also fly!

This animal makes a sound.
It can also swim!

This animal makes a sound.
It can also fly!
It can also swim!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Superclass vs. Decorator&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Superclass&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Decorator&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relationship&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inheritance (static relationship).&lt;/td&gt;
&lt;td&gt;Composition (dynamic behavior).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Add functionality via subclasses.&lt;/td&gt;
&lt;td&gt;Add functionality by wrapping objects.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple and straightforward.&lt;/td&gt;
&lt;td&gt;Slightly more complex due to composition.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When to Use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;For shared behavior across related objects.&lt;/td&gt;
&lt;td&gt;For customizing or extending the behavior of specific instances.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coupling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tightly coupled to the superclass.&lt;/td&gt;
&lt;td&gt;Loosely coupled, more flexible.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;When to Use vs. When Not to Use a Decorator&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When to Use a Decorator&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Behavior Customization:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Add or combine behaviors for specific objects without creating multiple subclasses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexible Extensibility:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Easily introduce new behaviors (e.g., "flying" or "swimming") without altering the base class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusable Logic:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Encapsulate behaviors that can be applied to different types of objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adherence to SOLID Principles:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Especially the Open/Closed Principle—extend functionality without modifying existing code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When Not to Use a Decorator&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When Behavior is Fixed:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If all objects of a class share the same behavior, a decorator may be overkill.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Sensitivity:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Wrapping objects may introduce slight overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When Simplicity Matters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For straightforward cases, inheritance (superclasses) might be simpler and easier to manage.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of Using a Decorator&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Behavior Addition:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Decorators allow you to add functionality to individual objects without altering their structure or creating new subclasses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modularity:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Behaviors are encapsulated in separate decorator classes, making them easier to manage and test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Behavior Combination:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You can stack multiple decorators to combine behaviors dynamically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoids Subclass Explosion:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No need to create numerous subclasses for every possible combination of behaviors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;When to Use a Superclass Instead&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While decorators shine in scenarios requiring flexibility, superclasses are better suited for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stable, Shared Behavior:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
When all subclasses share the same behavior (e.g., all &lt;code&gt;Dog&lt;/code&gt; objects can "bark").&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simpler Use Cases:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
When the relationship between objects is straightforward and unlikely to change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Wrapping Up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Choosing between a &lt;strong&gt;superclass&lt;/strong&gt; and a &lt;strong&gt;decorator&lt;/strong&gt; depends on your use case:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a &lt;strong&gt;superclass&lt;/strong&gt; for fixed, shared behaviors across related objects.
&lt;/li&gt;
&lt;li&gt;Use a &lt;strong&gt;decorator&lt;/strong&gt; for flexibility, dynamic behavior, or combining features without modifying existing code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our &lt;code&gt;Animal&lt;/code&gt; example, superclasses worked well for shared traits like eating or barking. On the other hand, decorators allowed dynamic additions like flying or swimming without altering the base class. Both patterns are powerful—pick the one that fits your design needs!&lt;/p&gt;

</description>
      <category>coding</category>
      <category>java</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Streamline Java Object Initialization with Inline Blocks (Including Public Fields)</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Wed, 04 Dec 2024 22:56:52 +0000</pubDate>
      <link>https://forem.com/mhossen/simplify-java-object-instantiation-with-an-inline-initialization-block-15bl</link>
      <guid>https://forem.com/mhossen/simplify-java-object-instantiation-with-an-inline-initialization-block-15bl</guid>
      <description>&lt;p&gt;When creating objects in Java, balancing simplicity, maintainability, and flexibility can be challenging. Developers often resort to techniques like constructors, the Builder pattern, or factory methods. While effective, these approaches can add unnecessary complexity for simple, one-off objects.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;inline initialization blocks&lt;/strong&gt;, a concise way to initialize both private fields (via setters) and public fields directly within the object creation context. In this blog, we’ll explore how to use this technique effectively, even when public fields are involved.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Inline Initialization Blocks?
&lt;/h2&gt;

&lt;p&gt;Inline initialization blocks in Java use double curly braces (&lt;code&gt;{{ }}&lt;/code&gt;) to configure an object immediately after instantiation. This approach simplifies object setup without requiring additional constructors or boilerplate code. Here’s an example:  &lt;/p&gt;

&lt;h3&gt;
  
  
  Updated Code with Public Fields
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SampleInlineInitialization&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;
      &lt;span class="n"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"John Smith"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setGender&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Male"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setAddress&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"123 Main St."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"@gmail.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Public fields&lt;/span&gt;
      &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"San Francisco"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CA"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}};&lt;/span&gt;

    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\"age\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAge&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", \"name\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", \"gender\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getGender&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", \"address\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAddress&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", \"email\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", \"city\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", \"state\": "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"}"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Getters and setters&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getAge&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getGender&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setGender&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getAddress&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAddress&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;John&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Smith&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"gender"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Male&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;St.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;John&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Smith@gmail.com&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;San&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Francisco&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CA&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Use Inline Initialization Blocks for Public Fields?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Flexibility for Public Fields&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Inline initialization supports direct assignment to public fields without requiring a setter. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"San Francisco"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CA"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps your code simple and avoids the need to define unnecessary setter methods for public fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Localized Configuration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;All field assignments—whether private or public—are conveniently located within the object instantiation block. This improves readability and maintainability by keeping the configuration logic in one place.  &lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Combines the Best of Both Worlds&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Inline initialization allows you to:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use setters for encapsulated private fields.
&lt;/li&gt;
&lt;li&gt;Assign public fields directly.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This dual capability makes it versatile for various scenarios.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Advantages of Using Inline Initialization Blocks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Eliminates Constructor Overloading
&lt;/h3&gt;

&lt;p&gt;Instead of writing multiple constructors to handle various field combinations, you can configure fields dynamically at the point of object creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;
  &lt;span class="n"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"John Smith"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"San Francisco"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CA"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Improves Readability
&lt;/h3&gt;

&lt;p&gt;By centralizing the object setup, inline initialization eliminates confusion about where and how fields are being assigned.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Reduces Boilerplate Code
&lt;/h3&gt;

&lt;p&gt;Say goodbye to redundant constructors and setters for every field. You can keep your class definition focused and clean.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Perfect for Prototyping
&lt;/h3&gt;

&lt;p&gt;Inline initialization is ideal for quick prototyping, testing, or creating objects with one-off configurations.  &lt;/p&gt;




&lt;h2&gt;
  
  
  When to Use Inline Initialization for Public Fields
&lt;/h2&gt;

&lt;p&gt;While inline initialization is convenient, it’s best suited for:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prototyping and Testing:&lt;/strong&gt; Quickly set up objects without adding unnecessary methods.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-Off Configurations:&lt;/strong&gt; Perfect for use cases where the object won’t need complex or reusable initialization logic.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight Use Cases:&lt;/strong&gt; Works well for small, simple objects where you want to minimize setup code.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Considerations for Public Fields
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Public Fields with Caution
&lt;/h3&gt;

&lt;p&gt;While public fields are straightforward, they may expose the class to unintentional misuse. Encapsulation via private fields and setters is generally safer for production code.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Anonymous Classes
&lt;/h3&gt;

&lt;p&gt;Inline initialization creates an anonymous subclass of the target class. While this rarely affects runtime behavior, debugging tools may display the subclass name instead of the original class name, which could be confusing in large projects.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Inline initialization blocks are a powerful way to simplify object creation in Java. By supporting both private and public field assignments, they strike a balance between flexibility and simplicity.  &lt;/p&gt;

&lt;p&gt;This approach eliminates the need for overloaded constructors, enhances readability, and reduces boilerplate code. Whether you’re prototyping, testing, or creating lightweight objects, inline initialization can save you time and effort while keeping your code clean and maintainable.  &lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>coding</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Efficient Data Sharing in SpecFlow Steps: A Cleaner Approach for Improved Maintainability</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Sat, 07 Oct 2023 22:11:16 +0000</pubDate>
      <link>https://forem.com/mhossen/efficient-data-sharing-in-specflow-steps-a-cleaner-approach-for-improved-maintainability-jj8</link>
      <guid>https://forem.com/mhossen/efficient-data-sharing-in-specflow-steps-a-cleaner-approach-for-improved-maintainability-jj8</guid>
      <description>&lt;p&gt;&lt;em&gt;Keywords&lt;/em&gt;: SpecFlow, data sharing, ScenarioContext, constructor injection, cleaner code, maintainability&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When working with SpecFlow, a popular BDD framework for .NET, efficient data sharing between steps is essential. While many developers rely on constructor injection for this purpose, this practice can lead to complex and hard-to-maintain code. In this technical blog post, we'll explore an alternative approach that not only streamlines data sharing but also minimizes the risk of data leaks.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Sharing Data Using ScenarioContext&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In SpecFlow, the &lt;code&gt;ScenarioContext&lt;/code&gt; class plays a pivotal role in facilitating data sharing. It functions as a versatile dictionary, allowing developers to store and retrieve objects associated with a particular scenario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseStep&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ScenarioContext&lt;/span&gt; &lt;span class="n"&gt;ScenarioContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;BaseStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ScenarioContext&lt;/span&gt; &lt;span class="n"&gt;scenarioContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ScenarioContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scenarioContext&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;p&gt;As shown in the code snippet above, we have a base step class that takes a &lt;code&gt;ScenarioContext&lt;/code&gt; parameter in its constructor, granting access to the &lt;code&gt;ScenarioContext&lt;/code&gt; within our step classes.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Data Sharing Without Constructor Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of injecting data via constructor parameters, we can leverage the &lt;code&gt;ScenarioContext&lt;/code&gt; directly to share data between steps. Let's dive into a practical example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Binding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddNewUserSteps&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseStep&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AddNewUserSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ScenarioContext&lt;/span&gt; &lt;span class="n"&gt;scenarioContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scenarioContext&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="nf"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I create a user"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WhenICreateAUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"jDoe@example.com"&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Store the user object in the ScenarioContext&lt;/span&gt;
        &lt;span class="n"&gt;ScenarioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="c1"&gt;// Implement actions to create the user via UI, API, or database&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;p&gt;Within the &lt;code&gt;WhenICreateAUser&lt;/code&gt; method, we create a &lt;code&gt;User&lt;/code&gt; object and store it in the &lt;code&gt;ScenarioContext&lt;/code&gt; using the &lt;code&gt;ScenarioContext.Set&lt;/code&gt; method. This enables other steps within the same scenario to access this shared data.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Retrieving Data Without Constructor Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, let's see how we can effortlessly retrieve the user object in another step without the need for constructor parameter injection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Binding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserAdminSteps&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseStep&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UserAdminSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ScenarioContext&lt;/span&gt; &lt;span class="n"&gt;scenarioContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scenarioContext&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="nf"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I verify the new user is listed on the admin page"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ThenIVerifyNewUserIsListedOnTheAdminPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="c1"&gt;// Retrieve the user object from the ScenarioContext&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScenarioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="c1"&gt;// Implement logic to verify the user's presence on the admin page&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"John"&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;p&gt;In the &lt;code&gt;ThenIVerifyNewUserIsListedOnTheAdminPage&lt;/code&gt; method, we employ the &lt;code&gt;ScenarioContext.Get&lt;/code&gt; method to retrieve the user object from the &lt;code&gt;ScenarioContext&lt;/code&gt;. This grants seamless access to data shared in a previous step.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Benefits of Not Using Constructor Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By eschewing constructor injection and capitalizing on &lt;code&gt;ScenarioContext&lt;/code&gt;, developers can reap several advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code Simplification&lt;/strong&gt;: The code becomes more straightforward and cleaner, eliminating the need to pass data through constructors and making it highly readable and maintainable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Flexibility&lt;/strong&gt;: Data can be shared between steps with unparalleled flexibility, enabling effortless modification and extension of the data sharing logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mitigated Data Leakage Risk&lt;/strong&gt;: Data sharing is confined within the scope of a scenario, significantly reducing the likelihood of data leakage between different scenarios or tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this technical blog post, we've unraveled an efficient methodology for sharing data between SpecFlow steps without resorting to constructor injection. By harnessing the power of &lt;code&gt;ScenarioContext&lt;/code&gt;, you can streamline your code, bolster its flexibility, and minimize the risk of data leaks. This approach empowers you to craft cleaner and more maintainable SpecFlow scenarios while ensuring that data is readily accessible where it's needed.&lt;/p&gt;

</description>
      <category>specflow</category>
      <category>automation</category>
      <category>cleancode</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Leveraging Interfaces and Dependency Injection for Flexible Code: A Practical Specflow Example</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Sat, 03 Jun 2023 14:20:58 +0000</pubDate>
      <link>https://forem.com/mhossen/leveraging-interfaces-and-dependency-injection-for-flexible-code-a-practical-specflow-example-16g</link>
      <guid>https://forem.com/mhossen/leveraging-interfaces-and-dependency-injection-for-flexible-code-a-practical-specflow-example-16g</guid>
      <description>&lt;p&gt;Introduction:&lt;br&gt;
Interfaces and dependency injection (DI) are powerful tools in software development that promote flexibility, testability, and maintainability. In this blog post, we'll explore a practical example that demonstrates how interfaces and DI can be used effectively. We'll analyze the code, explain its usage, and highlight the benefits it brings to the project.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding the Code
&lt;/h2&gt;

&lt;p&gt;Let's dive into the provided code snippet, which showcases the usage of interfaces and DI in a Selenium-based login page scenario. The code consists of several classes: &lt;code&gt;ILoginPage&lt;/code&gt;, &lt;code&gt;LoginPage&lt;/code&gt;, &lt;code&gt;ContainerExtension&lt;/code&gt;, &lt;code&gt;LoginSteps&lt;/code&gt;, &lt;code&gt;StepBase&lt;/code&gt;, and &lt;code&gt;Hooks&lt;/code&gt;. We'll discuss each component and its role in the overall implementation.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;ILoginPage&lt;/code&gt; Interface
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ILoginPage&lt;/code&gt; interface defines the contract for a login page. It declares two methods: &lt;code&gt;NavigateToLoginPage()&lt;/code&gt; and &lt;code&gt;Login(string username, string password)&lt;/code&gt;. This interface establishes the required behavior for any login page implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ILoginPage&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;NavigateToLoginPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;password&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;h3&gt;
  
  
  &lt;code&gt;LoginPage&lt;/code&gt; Class
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;LoginPage&lt;/code&gt; class implements the &lt;code&gt;ILoginPage&lt;/code&gt; interface and represents the actual login page. It extends a &lt;code&gt;BasePage&lt;/code&gt; class and includes private properties that represent various elements on the page, such as the username input field, password input field, and login button. The class also provides implementations for the interface methods.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;LoginPage&lt;/code&gt; constructor accepts an &lt;code&gt;IWebDriver&lt;/code&gt; parameter, which is passed from the DI container during object creation. This approach enables loose coupling between the &lt;code&gt;LoginPage&lt;/code&gt; and the &lt;code&gt;IWebDriver&lt;/code&gt; implementation, making the class more flexible and easier to test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginPage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BasePage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILoginPage&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IWebElement&lt;/span&gt; &lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IWebElement&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IWebElement&lt;/span&gt; &lt;span class="n"&gt;LoginButton&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CssSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input[value='Login']"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IWebDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&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;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;NavigateToLoginPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetParent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Navigate&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;GoToUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;\Sample\login.html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SendKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SendKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;LoginButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Click&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;h3&gt;
  
  
  &lt;code&gt;ContainerExtension&lt;/code&gt; Class
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ContainerExtension&lt;/code&gt; class extends the functionality of an &lt;code&gt;IObjectContainer&lt;/code&gt; (a DI container implementation) by introducing a method named &lt;code&gt;RegisterTypes&amp;lt;TBase&amp;gt;()&lt;/code&gt;. This method utilizes reflection to scan the assembly for all types derived from &lt;code&gt;TBase&lt;/code&gt; (in this case, &lt;code&gt;BasePage&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;For each derived type found, the code checks if there is an interface named &lt;code&gt;I{derivedType.Name}&lt;/code&gt; (e.g., &lt;code&gt;ILoginPage&lt;/code&gt; for &lt;code&gt;LoginPage&lt;/code&gt;). If a matching interface is found, an instance of the derived type is created using the provided arguments and registered with the DI container using the interface as the registration key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContainerExtension&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;RegisterTypes&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TBase&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;params&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TBase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;
  &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;var&lt;/span&gt; &lt;span class="n"&gt;typeOfBase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TBase&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;derivedTypes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;typeOfBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTypes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeOfBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsAssignableFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;IsClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IsAbstract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;derivedTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;derivedType&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;@interface&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;derivedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInterfaces&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;$"I&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;derivedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;@interface&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Activator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;derivedType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterInstanceAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;@interface&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;LoginSteps&lt;/code&gt; Class
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;LoginSteps&lt;/code&gt; class represents a set of steps defined for a specific behavior-driven development (BDD) framework, such as SpecFlow. It includes a constructor that accepts an &lt;code&gt;IObjectContainer&lt;/code&gt; and an &lt;code&gt;ILoginPage&lt;/code&gt; instance, which are resolved through DI.&lt;/p&gt;

&lt;p&gt;These steps correspond to scenarios defined in the BDD feature files. For example, the &lt;code&gt;GivenINavigateToLoginPage()&lt;/code&gt; step calls the &lt;code&gt;NavigateToLoginPage()&lt;/code&gt; method on the injected &lt;code&gt;ILoginPage&lt;/code&gt; instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILoginPage&lt;/span&gt; &lt;span class="n"&gt;_loginPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoginSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILoginPage&lt;/span&gt; &lt;span class="n"&gt;loginPage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;_loginPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loginPage&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="nf"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I navigate to login page"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GivenINavigateToLoginPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;_loginPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NavigateToLoginPage&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="nf"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I provide '(.*)' and '(.*)'"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GivenIProvide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;_loginPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&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;h3&gt;
  
  
  &lt;code&gt;StepBase&lt;/code&gt; Class
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;StepBase&lt;/code&gt; class serves as a base class for step definitions in a BDD framework. It includes a constructor that accepts an &lt;code&gt;IObjectContainer&lt;/code&gt;, allowing derived classes to access the DI container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StepBase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TechTalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SpecFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Steps&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;StepBase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&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;h3&gt;
  
  
  &lt;code&gt;Hooks&lt;/code&gt; Class
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Hooks&lt;/code&gt; class includes methods decorated with SpecFlow attributes, such as &lt;code&gt;[Before]&lt;/code&gt; and &lt;code&gt;[After]&lt;/code&gt;. These methods are executed before and after each scenario, providing setup and teardown functionality.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;BrowserSetup()&lt;/code&gt; method, a new instance of the Selenium &lt;code&gt;IWebDriver&lt;/code&gt; is created, and it is registered with the DI container using &lt;code&gt;RegisterInstanceAs()&lt;/code&gt;. Additionally, &lt;code&gt;RegisterTypes&amp;lt;BasePage&amp;gt;()&lt;/code&gt; is called on the DI container, which scans the assembly for all types derived from &lt;code&gt;BasePage&lt;/code&gt; and registers them as instances with their corresponding interfaces.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;BrowserTearDown()&lt;/code&gt; method disposes of the &lt;code&gt;IWebDriver&lt;/code&gt; instance retrieved from the DI container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Binding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hooks&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;Hooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&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="nf"&gt;Before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BrowserSetup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBrowserSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterInstanceAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterTypes&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BasePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IWebDriver&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BrowserTearDown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IWebDriver&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Dispose&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;
  
  
  Usage and Benefits
&lt;/h2&gt;

&lt;p&gt;To use the code sample, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define your own classes implementing the &lt;code&gt;ILoginPage&lt;/code&gt; interface, representing different login page implementations.&lt;/li&gt;
&lt;li&gt;Update the &lt;code&gt;RegisterTypes&amp;lt;BasePage&amp;gt;()&lt;/code&gt; call in the &lt;code&gt;BrowserSetup()&lt;/code&gt; method of the &lt;code&gt;Hooks&lt;/code&gt; class to include your custom page implementations.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;LoginSteps&lt;/code&gt; class to define step definitions for your BDD scenarios, injecting the &lt;code&gt;ILoginPage&lt;/code&gt; instance through the constructor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By leveraging interfaces and DI in this manner, you gain the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Interfaces allow you to switch between different login page implementations without modifying the consuming code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testability&lt;/strong&gt;: DI enables easy injection of mock objects for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;testing purposes, facilitating unit testing of classes dependent on the &lt;code&gt;ILoginPage&lt;/code&gt; interface.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Reusability&lt;/strong&gt;: The &lt;code&gt;LoginSteps&lt;/code&gt; class serves as a reusable component for defining login-related steps in multiple scenarios, promoting code reuse and reducing duplication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loose Coupling&lt;/strong&gt;: DI decouples classes from specific implementation details, making it easier to replace dependencies and promoting modular, decoupled code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By incorporating interfaces and DI into your projects, you can achieve cleaner, more modular code that is easier to maintain, test, and extend. The code provided in this blog post demonstrates practical usage and highlights the benefits of these concepts.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;Interfaces and dependency injection are powerful tools that enhance code flexibility, testability, and maintainability. By leveraging interfaces to define contracts and DI to inject dependencies, you can write cleaner, modular code that is easier to maintain and test.&lt;/p&gt;

&lt;p&gt;The code example showcased the usage of interfaces to define the contract for a login page and how DI can be employed to inject the &lt;code&gt;ILoginPage&lt;/code&gt; instance into the &lt;code&gt;LoginSteps&lt;/code&gt; class. Additionally, the code demonstrated how the &lt;code&gt;ContainerExtension&lt;/code&gt; class extends the DI container's functionality to register implementations based on interfaces.&lt;/p&gt;

&lt;p&gt;By adopting these practices in your own projects, you can improve code quality, support future scalability, and promote code reuse.&lt;/p&gt;

&lt;p&gt;GitHub Interface Example: &lt;a href="https://github.com/mhossen/SpecflowDependencyDemo/tree/selenium_specflow_di_interface_example" rel="noopener noreferrer"&gt;selenium_specflow_di_interface_example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>specflow</category>
      <category>csharp</category>
      <category>automation</category>
      <category>testing</category>
    </item>
    <item>
      <title>Simplifying Dependency Management with SpecFlow's IObjectContainer - Part 2</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Thu, 01 Jun 2023 01:38:14 +0000</pubDate>
      <link>https://forem.com/mhossen/simplifying-dependency-management-with-specflows-iobjectcontainer-part-1-revised-1laa</link>
      <guid>https://forem.com/mhossen/simplifying-dependency-management-with-specflows-iobjectcontainer-part-1-revised-1laa</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This is an updated version of our previous article, &lt;a href="https://dev.to/mhossen/simplifying-dependency-management-with-specflows-iobjectcontainer-part-1-354g"&gt;Simplifying Dependency Management with SpecFlow's IObjectContainer: Part 1&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to this blog post where we will delve deeper into the art of simplifying dependency management within SpecFlow by harnessing the power of constructor injection. In Part 1, we covered the fundamentals of constructor injection and its advantages. In this updated installment, we will explore this topic more comprehensively, providing additional insights and addressing key questions related to dependency injection in SpecFlow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Embrace Dependency Injection?
&lt;/h3&gt;

&lt;p&gt;Dependency injection is a pivotal software design pattern that champions loose coupling and code modularization. By embracing dependency injection, we can decouple the creation and management of dependencies from the core logic of our application. This decoupling paves the way for more straightforward testing, enhanced maintainability, and the flexibility to swap out implementations seamlessly.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does Dependency Injection Function in SpecFlow?
&lt;/h3&gt;

&lt;p&gt;SpecFlow, as a behavior-driven development (BDD) testing framework, offers its very own dependency injection framework named IObjectContainer. By leveraging IObjectContainer, we can effortlessly implement constructor injection within our SpecFlow step classes. IObjectContainer seamlessly takes care of resolving and injecting dependencies, rendering our code more modular and test-friendly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grasping the Code
&lt;/h3&gt;

&lt;p&gt;Let's revisit the code snippet we explored in Part 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Binding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginSteps&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StepBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt; &lt;span class="n"&gt;_loginPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoginSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt; &lt;span class="n"&gt;loginPage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_loginPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loginPage&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="nf"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I navigate to login page"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GivenINavigateToLoginPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_loginPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NavigateToLoginPage&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="nf"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I provide '(.*)' and '(.*)'"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GivenIProvide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_loginPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&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;p&gt;In this revised code, we've transformed the LoginSteps class to embrace constructor injection. The constructor now accepts two parameters: an instance of IObjectContainer and an instance of &lt;code&gt;LoginPage&lt;/code&gt;. Thanks to SpecFlow's IObjectContainer framework, these dependencies are resolved and provided automatically when creating a LoginSteps instance. This eliminates the need for manual dependency resolution via the &lt;code&gt;GetPage&amp;lt;TPage&amp;gt;()&lt;/code&gt; method from the StepBase class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of Constructor Injection
&lt;/h3&gt;

&lt;p&gt;Implementing constructor injection in SpecFlow yields numerous advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Enhanced Testability: Constructor injection simplifies the process of supplying mock implementations for testing purposes. This facilitates more effective and isolated unit testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleaner Code: Dependencies are explicitly defined and supplied during object creation, enhancing code readability and maintainability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Superior Separation of Concerns: Dependency injection separates the responsibility of managing dependencies from the core application logic, encouraging a modular and loosely coupled design.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;By embracing constructor injection within SpecFlow, we streamline dependency management, elevate the testability, and enhance the maintainability of our SpecFlow tests. SpecFlow's IObjectContainer framework handles dependency resolution and injection automatically. Constructor injection promotes cleaner code, improved separation of concerns, and simplified testing processes. Embrace this approach to simplify your SpecFlow projects and reap the benefits it offers. Stay tuned for Part 2, where we'll delve even deeper into this topic!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>specflow</category>
      <category>automation</category>
    </item>
    <item>
      <title>Simplifying Dependency Management with SpecFlow's IObjectContainer: Part 1</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Mon, 29 May 2023 18:33:10 +0000</pubDate>
      <link>https://forem.com/mhossen/simplifying-dependency-management-with-specflows-iobjectcontainer-part-1-354g</link>
      <guid>https://forem.com/mhossen/simplifying-dependency-management-with-specflows-iobjectcontainer-part-1-354g</guid>
      <description>&lt;h2&gt;
  
  
  Using Concrete Class Example
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In modern software development, managing dependencies is crucial for building scalable and maintainable applications. In this blog post, we will explore the importance of dependency management and how SpecFlow's IObjectContainer can streamline the process. We'll dive into your provided code example to understand why using IObjectContainer is beneficial, how to register dependencies using reflection, and the purpose of using a container for dependency registration in SpecFlow steps. While we will use a Selenium Page Object Model (POM) example for illustrating the concepts, it's important to note that the approach can be used for any type of object registration based on the testing demands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use IObjectContainer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SpecFlow's IObjectContainer serves as a dependency injection container, allowing for the easy management of dependencies in your SpecFlow tests. It helps achieve loosely coupled and modular code, promoting better testability, maintainability, and extensibility. By leveraging IObjectContainer, you can centralize dependency registration and resolve dependencies effortlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Register Dependencies with Reflection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the following code example, the &lt;code&gt;SeleniumDemo.SpecFlow.Hooks.ContainerExtension&lt;/code&gt; class provides an extension method called &lt;code&gt;RegisterTypes&lt;/code&gt;, which facilitates the registration of concrete classes using reflection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContainerExtension&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;RegisterTypes&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TBase&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;params&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TBase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;
  &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;var&lt;/span&gt; &lt;span class="n"&gt;typeOfBase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TBase&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;derivedTypes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;typeOfBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTypes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeOfBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsAssignableFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsClass&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAbstract&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;derivedTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;derivedType&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Activator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;derivedType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterInstanceAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;RegisterTypes&lt;/code&gt; method takes a generic parameter, &lt;code&gt;TBase&lt;/code&gt;, representing the base class from which the derived classes will be registered. It uses reflection to scan the assembly for types that are assignable from &lt;code&gt;TBase&lt;/code&gt;, concrete, and non-abstract.&lt;/p&gt;

&lt;p&gt;By iterating over the derived types, the &lt;code&gt;RegisterTypes&lt;/code&gt; method creates an instance of each derived type with the specified arguments and registers it with the IObjectContainer using the &lt;code&gt;RegisterInstanceAs&lt;/code&gt; method. This process eliminates the need for manual registration of each derived class, making it easier to maintain and extend the test suite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage of Container for Dependency Registration in SpecFlow Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In SpecFlow, steps are the building blocks of behavior-driven tests. Each step definition class represents a set of steps that can be executed during a scenario. By leveraging the IObjectContainer within the &lt;code&gt;StepBase&lt;/code&gt; class, you can effortlessly resolve dependencies required by these steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Binding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginSteps&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StepBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoginSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&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="nf"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I navigate to login page"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GivenINavigateToLoginPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GetPage&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;NavigateToLoginPage&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="nf"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"I provide '(.*)' and '(.*)'"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GivenIProvide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GetPage&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&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;p&gt;In the &lt;code&gt;LoginSteps&lt;/code&gt; class, the constructor accepts an &lt;code&gt;IObjectContainer&lt;/code&gt; parameter, allowing the container to be injected into the step definitions. This enables the use of the &lt;code&gt;GetPage&amp;lt;TPage&amp;gt;&lt;/code&gt; method, which resolves instances of concrete page classes derived from &lt;code&gt;BasePage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By utilizing the container to resolve page dependencies, you achieve better encapsulation and separation of concerns. The step definitions remain focused on the test logic, while the container handles the instantiation and management of page objects. This promotes maintainability and reusability, as any changes to the page classes can be easily propagated through the container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto Creation and Disposal of Driver Object with Container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this code example, the &lt;code&gt;Hooks&lt;/code&gt; class demonstrates how to leverage the IObjectContainer for automatic creation and disposal of the driver object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Binding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hooks&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;Hooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IObjectContainer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&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="nf"&gt;Before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BrowserSetup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBrowserSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterInstanceAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterTypes&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BasePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IWebDriver&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BrowserTearDown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IWebDriver&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Dispose&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;p&gt;The &lt;code&gt;BrowserSetup&lt;/code&gt; method is executed before the scenarios and is responsible for creating the browser session. It calls the &lt;code&gt;Driver.CreateBrowserSession&lt;/code&gt; method to obtain the driver object. The driver object is then registered with the IObjectContainer using the &lt;code&gt;RegisterInstanceAs&lt;/code&gt; method, making it available for dependency resolution throughout the test execution.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;BrowserTearDown&lt;/code&gt; method is executed after the scenarios and is responsible for disposing of the driver object. It retrieves the driver object from the container using the &lt;code&gt;Resolve&lt;/code&gt; method and calls the &lt;code&gt;Dispose&lt;/code&gt; method to properly clean up resources.&lt;/p&gt;

&lt;p&gt;By leveraging the IObjectContainer for driver object management, you ensure that the driver object is automatically created and disposed of, eliminating the need for manual management in each test scenario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dependency management is a critical aspect of software development, and SpecFlow's IObjectContainer provides a powerful tool for simplifying this process. By utilizing reflection and the container's registration capabilities, you can automate the registration of concrete classes, making your test suite more maintainable and extensible. Incorporating dependency injection into your SpecFlow steps promotes modular design and enhances collaboration between testers and developers. Embracing IObjectContainer empowers you to focus on writing expressive and efficient behavior-driven tests while enjoying the benefits of well-managed dependencies.&lt;/p&gt;

&lt;p&gt;The Selenium Page Object Model example used in this blog post highlights how IObjectContainer can simplify dependency management for BDD approaches, but it's important to note that the approach can be applied to any type of object registration based on the testing demands. With SpecFlow and IObjectContainer, you never have to register a dependency manually again, allowing for a more efficient and seamless testing experience. Additionally, the provided code example demonstrates how to automatically create and dispose of the driver object using the IObjectContainer, further simplifying the setup and teardown process in your tests.&lt;/p&gt;

&lt;p&gt;By embracing SpecFlow's IObjectContainer and leveraging its capabilities for dependency management, you can enhance the maintainability, extensibility, and efficiency of your behavior-driven tests.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/mhossen/SpecflowDependencyDemo/tree/selenium_specflow_di_concrete" rel="noopener noreferrer"&gt;Selenium Specflow DI Concrete example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>specflow</category>
      <category>selenium</category>
      <category>dotnetcore</category>
      <category>automation</category>
    </item>
    <item>
      <title>Simplify Web Automation with the WebDriver Extension for C#</title>
      <dc:creator>mhossen</dc:creator>
      <pubDate>Thu, 25 May 2023 05:08:19 +0000</pubDate>
      <link>https://forem.com/mhossen/simplify-web-automation-with-the-webdriver-extension-for-c-4603</link>
      <guid>https://forem.com/mhossen/simplify-web-automation-with-the-webdriver-extension-for-c-4603</guid>
      <description>&lt;p&gt;Web automation has become an essential part of modern software development and testing. One popular framework for web automation is Selenium WebDriver, which provides a powerful set of tools for interacting with web browsers. In this blog post, we will explore a C# extension method that enhances the capabilities of Selenium WebDriver by simplifying the process of locating elements using XPath.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use the WebDriver extension?
&lt;/h2&gt;

&lt;p&gt;The WebDriver extension we will discuss offers several advantages over the standard WebDriver methods:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Simplified element location&lt;/strong&gt;: The extension method allows you to locate elements using XPath in a more concise and readable manner. Instead of writing lengthy code to find elements, you can use the &lt;code&gt;WithXPath&lt;/code&gt; method to locate them with a single line of code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Automatic retries&lt;/strong&gt;: The extension method incorporates a built-in retry mechanism, which can be useful when dealing with dynamic web pages or slow-loading elements. By specifying the maximum retry time and interval, you can ensure that the method waits for the element to become available before timing out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Handling common exceptions&lt;/strong&gt;: The extension method handles common exceptions that may occur during element location, such as TimeoutException, StaleElementReferenceException, and NoSuchElementException. This simplifies error handling and improves the reliability of your automation code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use the WebDriver extension
&lt;/h2&gt;

&lt;p&gt;To use the WebDriver extension in your C# project, follow these steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add the extension method to your project
&lt;/h3&gt;

&lt;p&gt;Copy the provided C# code into a suitable location in your project, such as a helper class or a separate file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IWebElement&lt;/span&gt; &lt;span class="n"&gt;WithXPath&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TDriver&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;TDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;xpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxRetryInSeconds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;retryIntervalInMilliseconds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TDriver&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IWebDriver&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithActiveElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;XPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xpath&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;maxRetryInSeconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retryIntervalInMilliseconds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IWebElement&lt;/span&gt; &lt;span class="nf"&gt;WithActiveElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IWebDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;By&lt;/span&gt; &lt;span class="n"&gt;locateBy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxRetryInSeconds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;retryIntervalInMilliseconds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebDriverWait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxRetryInSeconds&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PollingInterval&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromMilliseconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retryIntervalInMilliseconds&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"Max element retry has reached at &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;maxRetryInSeconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IgnoreExceptionTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeoutException&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StaleElementReferenceException&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NoSuchElementException&lt;/span&gt;&lt;span class="p"&gt;)});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locateBy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Displayed&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enabled&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="k"&gt;null&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="n"&gt;IJavaScriptExecutor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ExecuteScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"arguments[0].scrollIntoViewIfNeeded(true);"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;element&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebDriverTimeoutException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&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;h3&gt;
  
  
  Step 2: Set up the WebDriver
&lt;/h3&gt;

&lt;p&gt;Create an instance of the WebDriver in your test or automation code, such as ChromeDriver or FirefoxDriver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Set up the WebDriver&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromeDriver&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Locate elements using XPath
&lt;/h3&gt;

&lt;p&gt;Instead of using the standard WebDriver methods like &lt;code&gt;FindElement(By.XPath(xpath))&lt;/code&gt;, you can now use the &lt;code&gt;WithXPath&lt;/code&gt; extension method on your WebDriver instance. Simply pass the XPath expression as a parameter to the method.&lt;/p&gt;

&lt;p&gt;Here's an example of how to use the WebDriver extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Locate elements using XPath&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithXPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"//input[@id='username']"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we use the &lt;code&gt;WithXPath&lt;/code&gt; method to locate an input element with the id attribute equal to "username." The method will automatically retry until the element is found within the specified timeout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: Null-coalescing operator (??) for C# 8+&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As of C# 8, the null-coalescing operator (??) can be used to simplify the code and throw a &lt;code&gt;WebDriverTimeoutException&lt;/code&gt; when the element is not found within the specified timeout. The null-coalescing operator works by returning the left-hand side expression if it is not null, or the right-hand side expression otherwise. In the case of the WebDriver extension, it can be used as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locateBy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Displayed&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enabled&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="k"&gt;null&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="n"&gt;IJavaScriptExecutor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ExecuteScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"arguments[0].scrollIntoViewIfNeeded(true);"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;element&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebDriverTimeoutException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using the null-coalescing operator, the &lt;code&gt;Until&lt;/code&gt; method will return the found element if it is not null, or the &lt;code&gt;throw new WebDriverTimeoutException(wait.Message)&lt;/code&gt; expression will be executed, throwing the exception with the specified message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The WebDriver extension for C# simplifies the process of locating elements using XPath in Selenium WebDriver. With its concise syntax, built-in retry mechanism, and exception handling, the extension enhances the productivity and reliability of your web automation code. By incorporating this extension into your project, you can streamline your test automation efforts and improve the efficiency of your web application testing.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>selenium</category>
    </item>
  </channel>
</rss>
