<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Harshad Lambate</title>
    <description>The latest articles on DEV Community by Harshad Lambate (@harshad_lambate).</description>
    <link>https://dev.to/harshad_lambate</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4166856%2Fea776e47-47f2-4c43-9613-fbaa0fa23e2d.jpg</url>
      <title>DEV Community: Harshad Lambate</title>
      <link>https://dev.to/harshad_lambate</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshad_lambate"/>
    <language>en</language>
    <item>
      <title>Your test passed on retry. Your report should say so.</title>
      <dc:creator>Harshad Lambate</dc:creator>
      <pubDate>Thu, 15 Oct 2026 15:28:16 +0000</pubDate>
      <link>https://dev.to/harshad_lambate/your-test-passed-on-retry-your-report-should-say-so-19b8</link>
      <guid>https://dev.to/harshad_lambate/your-test-passed-on-retry-your-report-should-say-so-19b8</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F68zexpc1xp4zit2xxl0w.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F68zexpc1xp4zit2xxl0w.png" alt="Sample Report" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most Java test suites have a retry somewhere: an IRetryAnalyzer in TestNG, @RetryingTest from JUnit Pioneer, or Surefire’s rerunFailingTestsCount. Retries keep pipelines green. They also hide information.&lt;/p&gt;

&lt;p&gt;When a test fails, gets retried and passes, most reports show one word: Passed. The failure that happened two minutes earlier, along with its stack trace, its API calls and the screenshot of what the browser showed, is gone. The test is flaky, and the report hides it.&lt;/p&gt;

&lt;p&gt;The second problem is quieter. To get a useful report, teams end up writing reporting code inside their tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`java
test.log(Status.INFO, "Calling POST /users");
test.log(Status.INFO, "Response: " + response.asString());
Allure.addAttachment("Screenshot", new ByteArrayInputStream(png));`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That code isn’t testing anything. People forget to add it, it drifts out of date, and it lands in every test for the rest of the project’s life.&lt;/p&gt;

&lt;p&gt;I built Ace Reports to fix both problems. Here’s what it does in Java.&lt;/p&gt;

&lt;p&gt;One dependency, no reporting code&lt;br&gt;
xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.acereports&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;acereports-junit5&amp;lt;/artifactId&amp;gt;  &amp;lt;!-- or acereports-testng / acereports-cucumber --&amp;gt;
    &amp;lt;version&amp;gt;1.1.0&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;There are no listeners to register, no base class and no annotations. Run mvn test as usual, and a single self-contained HTML file appears in TestResults/.&lt;/p&gt;

&lt;p&gt;Every attempt keeps its own history&lt;/p&gt;

&lt;p&gt;A test that fails and then passes on a retry is shown as flaky, with one tab per attempt. Each attempt keeps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;its own log lines,&lt;br&gt;
its own error and stack trace,&lt;br&gt;
its own API calls,&lt;br&gt;
its own screenshots.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So when attempt 1 timed out and attempt 2 passed, you can see exactly what was different. Pass, fail, flaky and retried counts sit at the top of the report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API calls are recorded automatically&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a typical API test with no reporting code in it:&lt;/p&gt;

&lt;p&gt;java&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
class UsersApiTest {&lt;br&gt;
    private final HttpClient client = HttpClient.newHttpClient();&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void createsUser() throws Exception {
    HttpResponse&amp;lt;String&amp;gt; response = client.send(
        HttpRequest.newBuilder(URI.create("https://reqres.in/api/users"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString("{\"name\":\"John\"}"))
            .build(),
        HttpResponse.BodyHandlers.ofString());
    assertEquals(201, response.statusCode());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The report’s API tab for this test shows the method, URL, request body, response body (JSON indented), status code and duration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST Assured calls are captured the same way, with no code.&lt;/strong&gt;&lt;br&gt;
Authorization and cookie headers are never stored.&lt;br&gt;
One limitation: a client created inside the test method itself can’t be reached automatically, so you wrap it once with AceHttpClient.wrap(...).&lt;br&gt;
Screenshots before teardown&lt;/p&gt;

&lt;p&gt;The failure screenshot is taken before @AfterEach / @AfterMethod runs, so the browser is still open. Ace Reports finds a Playwright Page or Selenium WebDriver in a field of the test class, a base class or a ThreadLocal by itself. A page that never navigated anywhere (about:blank) is skipped, so a failed API test doesn’t get an empty screenshot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cucumber: steps are the log&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Cucumber (JUnit 5 or TestNG runner), each scenario is a row and every step is a line in the log:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
GIVEN  the login page is open&lt;br&gt;
WHEN   I log in as "InvalidUser" with password "admin123"&lt;br&gt;
FAIL   Step failed.  TimeoutError: Timeout 3000ms exceeded.&lt;br&gt;
SKIPPED Then the dashboard is shown&lt;br&gt;
Scenario Outline rows carry their example values.&lt;br&gt;
Tags become categories.&lt;br&gt;
Images you attach with scenario.attach(...) show up as screenshot tabs.&lt;br&gt;
Writing to the report, when you want to&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You never have to, but you can:&lt;/p&gt;

&lt;p&gt;java&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
Ace.info("Submitting payment");&lt;br&gt;
Ace.takeScreenshot("After login");&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each line attaches to whichever test is running on the current thread, so parallel runs keep their logs apart.&lt;/p&gt;

&lt;p&gt;Same report in .NET, Java and Python&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ace Reports started in .NET (xUnit, NUnit, MSTest, Reqnroll) and Python (pytest, pytest-bdd).&lt;/strong&gt; The Java version produces the identical report, which helps when one team works across more than one stack.&lt;/p&gt;

&lt;p&gt;Try it&lt;br&gt;
&lt;strong&gt;Live demo report: **&lt;a href="https://harshadlambate.github.io/AceReportsWebsite/demo.html" rel="noopener noreferrer"&gt;https://harshadlambate.github.io/AceReportsWebsite/demo.html&lt;/a&gt;&lt;br&gt;
**Website and docs:&lt;/strong&gt; &lt;a href="https://harshadlambate.github.io/AceReportsWebsite/" rel="noopener noreferrer"&gt;https://harshadlambate.github.io/AceReportsWebsite/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Maven Central:&lt;/strong&gt; &lt;a href="https://central.sonatype.com/namespace/io.github.acereports" rel="noopener noreferrer"&gt;https://central.sonatype.com/namespace/io.github.acereports&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’d like to hear how your team handles flaky tests: do you keep the history of each attempt, or only the final result?&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>junit5</category>
      <category>testing</category>
      <category>api</category>
    </item>
    <item>
      <title>I built a .NET test reporter to solve two problems I kept seeing in test automation</title>
      <dc:creator>Harshad Lambate</dc:creator>
      <pubDate>Tue, 06 Oct 2026 16:04:00 +0000</pubDate>
      <link>https://dev.to/harshad_lambate/i-built-a-net-test-reporter-to-solve-two-problems-i-kept-seeing-in-test-automation-4mnk</link>
      <guid>https://dev.to/harshad_lambate/i-built-a-net-test-reporter-to-solve-two-problems-i-kept-seeing-in-test-automation-4mnk</guid>
      <description>&lt;p&gt;&lt;strong&gt;I built Ace Reports — a .NET test reporter with automatic API capture and flaky-test detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've been working on test automation for several years, and one thing I kept finding frustrating was that a test report would tell me that a test failed, but not enough about what actually happened during the failure.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Ace Reports&lt;/strong&gt; around two problems I wanted to solve:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Identify flaky tests and preserve their history&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a test fails and then passes on a retry, I don't want the report to simply show the final &lt;code&gt;Passed&lt;/code&gt; result. I want to know that the test was flaky, how many attempts it took, and what happened during those attempts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Don't make testers add reporting code to their tests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't want testers to have to modify their test scripts just to populate the report. Things like &lt;strong&gt;API requests/responses, retry information, execution details, and screenshots on failure should be captured automatically&lt;/strong&gt; wherever possible.&lt;/p&gt;

&lt;p&gt;The goal is that you write your tests normally, run them, and the report automatically contains the information needed to investigate failures.&lt;/p&gt;

&lt;p&gt;Ace Reports generates a self-contained HTML report, with no reporting server required. It currently has adapters for &lt;strong&gt;xUnit, NUnit, MSTest, and Reqnroll&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The project is available on NuGet and is currently at &lt;strong&gt;v1.0.1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I'd like to get feedback from people working with .NET test automation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What information do you wish your test reports captured automatically that they currently don't?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm especially interested in feedback around API capture, flaky-test detection, retries, and report usability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://harshadlambate.github.io/AceReportsWebsite/" rel="noopener noreferrer"&gt;https://harshadlambate.github.io/AceReportsWebsite/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3un2lc1uqapnio6e0j7e.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3un2lc1uqapnio6e0j7e.png" alt="Sample Report" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>analytics</category>
      <category>automation</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
