<?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: Mike Ralduxin</title>
    <description>The latest articles on DEV Community by Mike Ralduxin (@mike-ralduxin).</description>
    <link>https://dev.to/mike-ralduxin</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%2F274964%2F2936ad02-d039-442d-baff-044e7c2f9bbf.jpeg</url>
      <title>DEV Community: Mike Ralduxin</title>
      <link>https://dev.to/mike-ralduxin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mike-ralduxin"/>
    <language>en</language>
    <item>
      <title>How to Cut Regression Testing from Weeks to Hours Without Automating Everything</title>
      <dc:creator>Mike Ralduxin</dc:creator>
      <pubDate>Mon, 31 Aug 2026 15:23:25 +0000</pubDate>
      <link>https://dev.to/deviqa-solutions/how-to-cut-regression-testing-from-weeks-to-hours-without-automating-everything-448o</link>
      <guid>https://dev.to/deviqa-solutions/how-to-cut-regression-testing-from-weeks-to-hours-without-automating-everything-448o</guid>
      <description>&lt;p&gt;A healthcare platform I worked with needed two and a half weeks to complete a regression pass. Smoke testing alone took seven days. The obvious recommendation — the one everyone reaches for — was "automate everything." It would also have been the wrong place to start.&lt;/p&gt;

&lt;p&gt;Here's the trap. If you point automation at a bloated, outdated, UI-heavy suite, you don't get fast regression. You get an oversized, expensive, automated version of the same slow process, plus a maintenance bill that grows every sprint. A faster test runner does not create a faster regression process — it just runs the wrong tests more quickly.&lt;/p&gt;

&lt;p&gt;The teams that actually go from weeks to hours don't start with the runner. They start by asking where the time is really going — and most of it is not in test execution. On that healthcare platform, we eventually got regression down from 2.5 weeks to a single day while raising coverage from 50% to 90%. Automation was part of it. It was nowhere near the whole story.&lt;/p&gt;

&lt;p&gt;This is a guide to the whole story: what to cut, where to test, when to run, and how to investigate failures — so that automation removes specific bottlenecks instead of freezing an inefficient manual suite into code.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why regression testing takes weeks&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The first thing to fix is a measurement mistake. Most teams track test execution time and quietly assume it's the same thing as regression lead time. It isn't, and the gap between them is where your weeks disappear.&lt;/p&gt;

&lt;p&gt;Regression lead time = preparation + environment setup + queue time + execution + failure investigation + reruns + reporting&lt;/p&gt;

&lt;p&gt;Execution is one term in that sum, and often not the biggest. You can halve your runtime and still ship on the same day if the other six terms are untouched. Before you optimize anything, break your lead time into these buckets and see which one actually hurts. In my experience it's rarely the one people complain about.&lt;/p&gt;

&lt;p&gt;Here's where the time usually leaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  The suite grows but never shrinks
&lt;/h3&gt;

&lt;p&gt;Every team is good at adding tests. Almost none are disciplined about removing them. So the suite accretes scenarios that are duplicated across specs, outdated relative to the current product, disconnected from any real risk, already covered at a lower level, or so vaguely written that a pass or fail tells you nothing. That's not coverage. It's ballast — and you re-run it on every release, forever, until someone decides to look.&lt;/p&gt;

&lt;h3&gt;
  
  
  Every test runs for every change
&lt;/h3&gt;

&lt;p&gt;A one-line copy edit on a marketing page should not trigger the same regression scope as a change to the payments flow, the authentication layer, or a database migration. When it does, you're paying the worst-case validation cost on every release regardless of actual risk. Teams need more than one suite, sized to different levels of risk — not a single monolith that runs identically no matter what changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too many checks live at the UI level
&lt;/h3&gt;

&lt;p&gt;UI end-to-end tests are the slowest, most fragile, and most expensive-to-maintain layer you have. They break when a selector shifts, they need a running environment and real data, and they retry slowly. That doesn't make UI tests useless — but the UI is the wrong place to verify a business rule you could assert against an API or a service in a fraction of the time, with far less flake. The classic test pyramid exists for exactly this reason, and most slow suites are shaped like an inverted one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environments and test data are prepared by hand
&lt;/h3&gt;

&lt;p&gt;This is the quiet killer. Automation can't compensate for an environment that behaves differently every run. If your team is manually configuring environments, sharing mutable accounts, hand-seeding databases, depending on third-party services you can't control, and relying on tests running in a specific order, then a good chunk of your "regression time" is really setup and firefighting. The tests are just where the instability finally surfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failures take longer to investigate than tests take to run
&lt;/h3&gt;

&lt;p&gt;A two-hour run can still block a release for two days. Once it goes red, someone has to work out whether the failure is a real product defect, a broken test, an environment hiccup, a bad data state, or a flaky third-party call. If that triage is slow and manual, investigation — not execution — is your bottleneck. I've seen teams shave twenty minutes off runtime and celebrate, while the two days of failure analysis after each run sat completely untouched.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cut the regression scope before accelerating execution&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The cheapest speedup is the test you stop running. Before touching the runner, shrink and reshape what regression even means.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit the existing suite.&lt;/strong&gt; Go through it — ideally the slowest and most-changed specs first — and put five questions to every test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What product risk does this test actually cover?&lt;/li&gt;
&lt;li&gt;Has it caught a meaningful defect in recent memory?&lt;/li&gt;
&lt;li&gt;Is the same behavior already verified somewhere else?&lt;/li&gt;
&lt;li&gt;Does it still reflect how the product works today?&lt;/li&gt;
&lt;li&gt;Does it genuinely need to run before every release?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A test that can't be tied to a current risk gets updated to match reality, demoted to a less frequent suite, or deleted. Deleting tests makes people nervous, so be concrete about the trade-off: a test that verifies nothing anyone can name is not protecting you — it's taxing every release for coverage theater.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Split regression by risk and purpose.&lt;/strong&gt; Once the suite is honest, stop treating it as one thing. A practical structure has four tiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PR checks — fast API, component, and critical smoke tests, on every pull request.&lt;/li&gt;
&lt;li&gt;Critical regression — core revenue, security, authentication, and data flows, on merge to main.&lt;/li&gt;
&lt;li&gt;Extended regression — secondary workflows and less common edge cases, nightly.&lt;/li&gt;
&lt;li&gt;Compatibility regression — browsers, devices, operating systems, and localizations, before release or on demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point isn't the exact names. It's that these suites don't all need to run at the same moment in the delivery cycle, so you stop paying compatibility-matrix costs to validate a backend bug fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use change-based test selection.&lt;/strong&gt; You don't need an AI platform to run fewer tests intelligently. Start with plain mapping: for a given change, what product area moved, which services and integrations it touches, which critical user journeys depend on it, where defects have clustered historically, and which platforms or locales are at risk. Run the tests that give the strongest signal for this change. The goal is never "run fewer tests at random" — it's "run the tests that matter for what actually changed," and let the full extended and compatibility passes happen on their own cadence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate the bottleneck — not the entire suite
&lt;/h2&gt;

&lt;p&gt;Now, and only now, automation. The discipline here is subtractive: automate the specific thing that's slow and repetitive, not the entire inventory.&lt;/p&gt;

&lt;p&gt;A test is a strong automation candidate when it's run often, tied to a high-impact risk, stable enough to give deterministic results, expensive or slow to do by hand, backed by data you can create programmatically, and needed across several environments or configurations. Those tests pay back the automation cost quickly and keep paying.&lt;/p&gt;

&lt;p&gt;Just as important: decide what stays manual, on purpose. Manual testing is not a legacy practice you're phasing out. Keep humans on exploratory testing, brand-new or fast-changing features, usability and subjective UX judgment, rare scenarios where automation maintenance would cost more than it saves, visual or physical interactions that are hard to model reliably, and any failure that needs real investigative judgment. The aim is to remove repetitive manual regression, not human testing — those are different things, and confusing them is how teams end up with brittle automation and no one who actually understands the product.&lt;/p&gt;

&lt;p&gt;Move checks below the UI. This is where the title's promise is kept. Validate business rules at the service or API level, test integration boundaries on their own, keep UI automation focused on a small set of critical end-to-end journeys, and stop asserting the same fact through three layers.&lt;/p&gt;

&lt;p&gt;ChargeAfter, a payments platform, &lt;a href="https://www.deviqa.com/case-studies/chargeafter/" rel="noopener noreferrer"&gt;shows&lt;/a&gt; what this buys you. Its regression cycle dropped from two weeks to six hours — and the lever was structural, not the raw script count. We built 1,000+ automated API tests and around 4,000 combined UI and API scripts (Cypress and Playwright), reached roughly 90% coverage, then arranged them by when they run: a 10-minute API suite after every pull request, smoke tests every two hours (each 15–20 minutes), all on a dedicated environment with multiple pipelines and 12 parallel threads. The six-hour number came from API-level coverage, CI triggers, environments, and parallelism working together. If we'd simply recorded 4,000 UI scripts and hit "run," we'd have built a slower, flakier two-week suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Reduce execution and waiting time&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With scope cut and the right things automated, attack the remaining lead-time buckets: setup, queue time, and reruns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stabilize environments and data first — before adding a single worker.&lt;/strong&gt; Automation on top of an unpredictable environment just produces fast, confident nonsense. What "stable" looks like in practice: dedicated or reproducible test environments, data factories and API-based data creation instead of hand-seeded databases, isolated accounts per parallel worker, a health check that fails fast if the environment is sick before you run 3,000 tests against it, controlled stubs or mocks for external dependencies you can't govern, and automatic cleanup so one run doesn't poison the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then parallelize — carefully.&lt;/strong&gt; Parallel execution is not "turn the worker count up." It's a property your tests have to earn. Before scaling out, the suite must not depend on execution order, must not have two tests mutating the same records, must be able to create isolated data per worker, must fit inside the environment's capacity, and should distribute evenly so you're not waiting on one 40-minute shard while eleven others sit idle.&lt;/p&gt;

&lt;p&gt;The payoff is real when the groundwork is there. Across projects I've seen 10 parallel threads on Abbott, 12 on ChargeAfter, 15 on GoodShape, and up to 20 on CipherHealth — a healthcare product running 1,400+ E2E and 250+ API tests to a five-hour regression pass. But the trade-off has to be said plainly: parallel execution amplifies your existing data and environment problems — it does not fix them. Point twenty workers at shared mutable data and you don't get twenty times the speed. You get twenty times the flake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the right suite at the right time.&lt;/strong&gt; Tie each suite to a pipeline stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull request:&lt;/strong&gt; API checks and critical smoke tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Main branch:&lt;/strong&gt; critical regression&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nightly:&lt;/strong&gt; extended regression&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Before release:&lt;/strong&gt; compatibility and high-risk end-to-end scenarios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On demand:&lt;/strong&gt; localization, migration, performance, specialized suites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Handle fail-fast with judgment, not as a global switch. Aborting a run after a major infrastructure failure saves CI time and is the right call. Aborting after the first ordinary test failure often hides the three other real defects that run would have surfaced, and you learn about them one painful cycle at a time. The value can also be in the rerun and failure-handling logic itself: on Xola, a booking platform doing 5–10 releases a working week, we &lt;a href="https://www.deviqa.com/case-studies/xola/" rel="noopener noreferrer"&gt;cut&lt;/a&gt; the main automation build from about an hour to roughly 20 minutes largely by fixing how the pipeline handled internal reruns and early failure detection — not by rewriting the tests. That same pipeline work is what surfaces about 70% of blocker, critical, and major bugs early.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Make the regression suite trustworthy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A fast suite that engineers don't believe is worthless. The moment people start re-running "just to be sure" or waving through red builds, you've lost the entire point of regression, however quick it is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treat flakiness as a defect, not weather.&lt;/strong&gt; Flaky tests are more common than teams admit — Google's widely cited &lt;a href="https://testing.googleblog.com/2016/05/flaky-tests-at-google-and-how-we.html" rel="noopener noreferrer"&gt;analysis&lt;/a&gt; found that almost 16% of their tests had some level of flakiness and about 1.5% of all test runs reported a flaky result, at a company with serious testing infrastructure. So track flaky tests separately from product failures, give every unstable test a named owner, quarantine only temporarily, record why something was quarantined, and put a deadline on repair-or-removal. Retries have a legitimate use — diagnosing an intermittent failure — but unlimited retries to manufacture a green build is just hiding a defect behind a loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classify failures automatically.&lt;/strong&gt; When a run goes red, the expensive part is figuring out what kind of red. Bucket failures into assertion/product failures, locator/automation failures, test-data failures, environment failures, and network/third-party failures — and surface that classification in the report. Getting an engineer to "this is an environment failure, not your code" in thirty seconds is often worth more than shaving five minutes off raw execution. Triage time is lead time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep maintenance under control.&lt;/strong&gt; Review tests when the related functionality changes, delete obsolete ones instead of muting them, keep selectors and test data separate from business logic so a UI tweak doesn't cascade, watch your slowest tests, and actually measure the engineering hours going into suite upkeep. And stop treating test count as a success metric. "We have 6,000 automated tests" tells me nothing about whether you can ship on Friday.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What the results can look like&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Numbers help, as long as they're read correctly: these are outcomes from specific engagements, not benchmarks you'll hit by copying one tactic.&lt;/p&gt;

&lt;p&gt;The healthcare platform from the opening is the fullest example. When we started, &lt;a href="https://www.deviqa.com/case-studies/abbott-laboratories/" rel="noopener noreferrer"&gt;Abbott&lt;/a&gt; ran regression in 2.5 weeks and smoke testing in 7 days, on 50% coverage, with outdated test cases, no automation in place, and just 5 test devices. After the rebuild: regression in 1 day, smoke in 1 day, coverage at 90%, the relevant regression scope up 60%, 1,500 automated scenarios (part of 1,600+ automated test cases), 10 parallel threads, 20+ devices, and 27 localizations with about 70% of translations covered by autotests — run across 4 browsers by a team of 8 automation and 11 manual QA engineers.&lt;/p&gt;

&lt;p&gt;Read those numbers carefully, because the tempting misreading is "automation did this." It didn't. The transformation came from cleaning up outdated test cases, widening relevant coverage by 60% rather than just encoding what existed, a real device and localization strategy, CI integration, and parallel execution — with the 1,500 automated scenarios as one component among several.&lt;/p&gt;

&lt;p&gt;Other engagements point the same direction, with numbers worth reading closely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.deviqa.com/case-studies/cipher-health/" rel="noopener noreferrer"&gt;CipherHealth&lt;/a&gt;: a five-hour regression pass and a ten-minute smoke suite on 20 parallel threads (1,400+ E2E and 250+ API scripts, 90% of features covered). Production bugs fell 35% in the first seven months, and the product passed 240+ successful releases — up from a baseline where 20% of releases shipped with major bugs.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.deviqa.com/case-studies/planetly/" rel="noopener noreferrer"&gt;Planetly&lt;/a&gt;: regression in under an hour and smoke in under ten minutes, from 400+ end-to-end tests at roughly 90% coverage — about a 3x cut in regression time versus the earlier manual process.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.deviqa.com/case-studies/goodshape/" rel="noopener noreferrer"&gt;GoodShape&lt;/a&gt;: 90%+ of test cases automated (~3,800 scripts, ~95% overall coverage, ~99% of smoke automated) and a roughly 95% drop in post-release regression bugs, with regression running about 2x faster.&lt;/li&gt;
&lt;li&gt;Xola: regression held to one to two hours across 3,200+ scripts and 8,300+ checks (90% coverage, 160+ devices) while shipping 5–10 releases a working week.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different stacks, different tactics — none got there by automating their existing suite as-is.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A practical implementation plan&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Treat this as a shape, not a schedule. The durations depend entirely on your starting mess.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1 — Establish the baseline.&lt;/strong&gt; Measure full regression lead time and split it into preparation, waiting, triage, and reruns. Identify the slowest and least reliable tests. Write down your current release risks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2 — Reduce and restructure.&lt;/strong&gt; Remove obsolete and duplicate tests. Create the critical, extended, and compatibility suites. Map tests to risks and product areas. Decide which suite runs at which pipeline stage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3 — Automate high-value bottlenecks.&lt;/strong&gt; Start with the critical, repetitive scenarios. Add API-level coverage before expanding UI automation. Automate test-data creation. Add fast PR and smoke checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4 — Improve execution.&lt;/strong&gt; Introduce isolated parallel workers, optimize the slowest tests, make environments reproducible, and add automatic reporting and failure classification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 5 — Stabilize and maintain.&lt;/strong&gt; Track flakiness, assign test ownership, review the suite continuously, and keep removing tests that no longer cover real risk. The cleanup in Phase 2 is not a one-time event.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to measure whether the strategy worked&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Do not use the raw count of automated tests as your headline metric. It rewards exactly the bloat you're trying to remove. Track instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total regression lead time (the real number)&lt;/li&gt;
&lt;li&gt;Execution time per suite&lt;/li&gt;
&lt;li&gt;Time to first useful failure&lt;/li&gt;
&lt;li&gt;Smoke-suite duration&lt;/li&gt;
&lt;li&gt;Failure investigation time&lt;/li&gt;
&lt;li&gt;Flaky-test rate and rerun rate&lt;/li&gt;
&lt;li&gt;Percentage of critical risks actually covered&lt;/li&gt;
&lt;li&gt;Escaped regression defects and overall post-release defect rate&lt;/li&gt;
&lt;li&gt;Automation maintenance effort&lt;/li&gt;
&lt;li&gt;Release frequency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And hold one uncomfortable idea alongside these: higher coverage is not automatically better. Ninety percent coverage that's slow, flaky, or aimed at low-risk corners of the product is worse than seventy percent that's fast, trusted, and pointed at the flows that generate revenue and lose customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The shift that actually matters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You don't cut a multi-week regression cycle by automating every test. You cut it by refusing to treat regression as one enormous suite that runs the same way for every release.&lt;/p&gt;

&lt;p&gt;Three things to take away:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduce the scope before you accelerate it.&lt;/strong&gt; The fastest test is the one you correctly stopped running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate the bottleneck, not the inventory.&lt;/strong&gt; Encode the slow, repetitive, high-risk checks — and push them below the UI wherever you can.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimize the whole feedback loop, not just execution.&lt;/strong&gt; Preparation, environments, queueing, triage, and reruns are usually where your weeks are hiding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the same principles we lean on when rebuilding regression testing and test automation strategy for products that can no longer afford multi-day release validation. Start by measuring where your lead time actually goes. It's almost never where you think.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>automation</category>
      <category>qa</category>
    </item>
    <item>
      <title>Complete Guide on How to Build a Maintainable Selenium Framework</title>
      <dc:creator>Mike Ralduxin</dc:creator>
      <pubDate>Thu, 28 Jan 2021 10:38:55 +0000</pubDate>
      <link>https://dev.to/deviqa-solutions/complete-guide-on-how-to-build-a-maintainable-selenium-framework-15n5</link>
      <guid>https://dev.to/deviqa-solutions/complete-guide-on-how-to-build-a-maintainable-selenium-framework-15n5</guid>
      <description>&lt;p&gt;Selenium is second to none when it comes to &lt;a href="https://www.deviqa.com/blog/best-automation-testing-tools/" rel="noopener noreferrer"&gt;automation testing tools&lt;/a&gt;. Thousands of automation QA engineers efficiently use it every day to facilitate the execution of testing. If you are a newbie and want to get the philosophy of Selenium, there are some tips on how to get the most out of it and create a maintainable and robust Selenium automation framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  A brief overview of the Selenium framework
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.selenium.dev/" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt; framework can be defined as a set of testing tools, patterns, and practices that provide opportunities for efficient &lt;a href="https://www.deviqa.com/services/automation-testing-services/" rel="noopener noreferrer"&gt;test automation&lt;/a&gt;, code readability, and easy code maintenance.&lt;/p&gt;

&lt;p&gt;A plenty of automation framework types are differentiated. Still, if you prefer to work with Selenium, you can build three of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data-driven framework&lt;/strong&gt; splits test script logic off from test data. It gives an opportunity to store test data in external storage. For this purpose, a QA engineer can use MS Excel Sheets, SQL Database, CSV files, text files, XML files, ODBC sources, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keyword-driven framework&lt;/strong&gt; speeds up the process of automated testing. Each set of functions and instructions also stored in an external file has a particular keyword. As a result, QA engineers can easily pick up functions for testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As its name implies, &lt;strong&gt;a hybrid framework&lt;/strong&gt; is a combination of two previous frameworks. Either test data or keywords are externalized. While keywords are placed in a segregated Java class file, test data is located in an Excel file or Properties file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a great volume of data should undergo testing, a data-driven framework is definitely the best choice. If you are going to deal mostly with functionalities, it is better to apply a keyword-driven framework. In situations when a large volume of either data or functions should be tested, it makes sense to leverage a hybrid framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do We Need A Selenium Framework?
&lt;/h2&gt;

&lt;p&gt;Selenium framework considerably simplifies the work of automation QA engineers. Code and data would be kept together without a framework, and it would heavily affect reusability and readability. When it is properly developed and implemented, the Selenium framework brings multiple advantages such as code reuse and readability, better portability, easier code maintenance, minimum human intervention during test running, maximum test coverage, easy reporting, and many others.&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%2Fi%2F2o4jrhsvactppl7jbuou.jpg" 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%2Fi%2F2o4jrhsvactppl7jbuou.jpg" alt="Advantages Selenium Framework" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Merits of the Selenium automation framework
&lt;/h2&gt;

&lt;p&gt;Numerous merits make the Selenium automation framework so popular among QA experts from different corners of the world. Let's have a look at its main advantages to understand why it is an unbeatable automation testing tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Availability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium is freely available, and everyone can use it without paying a penny whereas most other solutions are commercial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Most user actions can be reproduced&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium WebDriver can copy the most various user actions. Therefore, QA engineers can automate various inputs like dragging and dropping, mouse-clicking, button pressing, clicking and holding, and so on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;User-friendliness&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium automation framework is easily implemented and easy-to-use. Its interface is pretty simple as well. Besides, QA experts can enrich their frameworks with different extensions according to their needs and project requirements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The most various scenarios can be covered&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium provides various options; that is why every QA expert most likely finds something that suits their scenario.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multilingual capability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is indeed a helpful feature of Selenium. QA experts enjoy freedom while choosing a programming language. Building the Selenium automation framework they can use Java, C#, JavaScript, Python, Ruby, Perl, or PHP.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cross-browser compatibility&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium supports all commonly used browsers — Safari, Chrome, Opera, Firefox, Edge, Internet Explorer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Support of various operating systems&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium supports such OSs as Windows, Linux, Mac, UNIX, etc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integration with numerous tools&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To significantly simplify automated testing, Selenium smoothly integrates with numerous tools. For instance, integration with TestNG &amp;amp; JUnit enables test case management and report generation. Integration with &lt;a href="https://maven.apache.org/" rel="noopener noreferrer"&gt;Maven&lt;/a&gt;, &lt;a href="https://www.jenkins.io/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;, and &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; gives an opportunity for deployment process automation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reusability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Created scripts are compatible with different browsers. As a result, QA engineers can run numerous testing scenarios utilizing the same base.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Maintainability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;QA experts can quickly modify code and easily maintain scripts due to an opportunity to refactor and group their test cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Community Support&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Selenium community is indeed wide and active. As a result, a ton of information can be found, and valuable pieces of advice can be received when QA experts need them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unique options&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Selenium WebDriver, QA experts can reproduce clicking on the browser “back” and “forward” buttons. This feature can be pretty useful in some situations and most other solutions do not offer it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to build maintainable Selenium framework
&lt;/h2&gt;

&lt;p&gt;A maintainable and reliable test automation framework is 50% of test automation success as it enables QA experts to create effective test scripts. Below you can find some aspects you should take into consideration to build a robust Selenium automation framework.&lt;/p&gt;

&lt;p&gt;To create a framework that would satisfy all your needs, it is vital to identify processes that should be automated. That is why you should study the internal structure and workflows of your application to understand which processes can be and must be automated and define requirements for your future test automation framework.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Programming language&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As we have already mentioned, Selenium supports plenty of programming languages and you should decide which one to use for your framework design. In this case, we advise you consider a language that has been used for your application development or a language at which most of your colleagues are good.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Framework architecture&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium framework architecture consists of the Selenium Core component and the Selenium Test component. It is advised to begin with the Selenium Core component which controls browser instances and element interactions. As soon as your Selenium Core component is ready, you can proceed to the Selenium Test component. You can use a page object model (POM) to design this component. It is indeed very useful due to its ability to eliminate code redundancy and cut down testing expenses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unit framework&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unit framework is utilized for test verification and test case grouping and prioritization. Working on your automation framework development you should choose a unit framework that will be integrated. In these terms, TestNG is considered as one of the best unit frameworks for Selenium as it offers multiple benefits, among which are such valuable features as parameterizing, sequencing, annotations, and grouping.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CI/CD implementation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get the most out of your automation framework you should also consider CI/CD implementation. In these terms, a range of helpful tools should be integrated with your framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dependency managers like Maven, NuGet, Gradle, NPM, and Ant give an opportunity to efficiently manage dependencies and librarie. Build tools also come in handy when it comes to source code writing, dependent library creation, and test running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Version control systems as GitHub, Bitbucket, or TFS significantly simplify work on the source code of your tests. Still, if your source code should be kept private, it is highly advised to implement your own version control system using Git.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To speed up product delivery and get a competitive advantage, it is essential to integrate automated tests into CI/CD pipelines. That is why, integration with one of the CI tools such as Jenkins, TFS, or Bamboo is a must.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Report generation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A reliable test automation framework should also provide test results generating accurate testing reports. These reports should be clear, readable, and available for either technical or non-technical staff who need them. As Selenium does not provide a built-in report option, you should integrate an external tool. For instance, you can utilize TestNG or JUnit. However, reports generated by these tools are not readable. To create human-readable reports, external libraries like ExtentReport or Allure should be used.&lt;/p&gt;

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

&lt;p&gt;Test automation can significantly simplify and optimize testing processes. However, to achieve excellent results, it is essential to prepare a strong foundation, i.e., create an effective test automation framework. In these terms, Selenium is the best choice. It provides almost everything you need, while options that are not available still can be used due to integration with multiple tools. While building your Selenium automation framework, you should take into consideration numerous aspects as project requirements, processes that should be automated, programming language, framework architecture, unit framework, report generation, CI/CD implementation, etc. Still, at the end of the day, all efforts will be justified because a well-thought framework enables QA team members to create effective automated scripts and maintain them easily.&lt;/p&gt;

</description>
      <category>selenium</category>
      <category>automation</category>
      <category>testing</category>
    </item>
    <item>
      <title>Manual Testing Guide</title>
      <dc:creator>Mike Ralduxin</dc:creator>
      <pubDate>Tue, 29 Sep 2020 08:40:32 +0000</pubDate>
      <link>https://dev.to/deviqa-solutions/manual-testing-guide-565k</link>
      <guid>https://dev.to/deviqa-solutions/manual-testing-guide-565k</guid>
      <description>&lt;p&gt;Testing is one of the most important stages of the software development life cycle. These days, there are two main approaches to software testing: manual and automated. Most QA teams skillfully combine both approaches as they are not entirely interchangeable and have either advantages or disadvantages. We are going to consider manual testing in detail. So let's start from scratch and consider the manual testing basics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition of manual testing
&lt;/h2&gt;

&lt;p&gt;Manual testing is a software examination and utilization from the end-user perspective to assess its quality, detect existing defects, and uncover possible weaknesses. In contrast to automated testing that utilizes a software program to conduct tests, manual testing reckons upon human's actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual testing process
&lt;/h2&gt;

&lt;p&gt;As a rule, to provide professional and comprehensive testing, most manual testers organize their workflow in the following way:&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirement studying
&lt;/h3&gt;

&lt;p&gt;Manual testers must get acquainted with the requirements to ensure a successful QA process. Thus, they can understand the software's objective, operation principles, main functions, and possible vulnerabilities. Testers can make up excellent test cases and identify more defects using this information. However, project specifications and user stories are not always available. In this case, manual testers should be more inventive and check other information resources to realize how an application should work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Drawing up of test cases
&lt;/h3&gt;

&lt;p&gt;As soon as manual testers have gotten acquainted with project requirements, they start to draw up test cases using various test design techniques. Test cases are used as instructions for manual testers, as they contain the consecutive steps for a particular function or scenario testing. They should be rather detailed. Therefore, other testers will also be able to carry out your tests, not asking clarification questions.&lt;br&gt;
Some manual testers still use an Excel document to file their test cases. However, various case management tools are available; they can significantly simplify test case creation, storage, and management.&lt;/p&gt;

&lt;p&gt;Useful articles:&lt;br&gt;
&lt;a href="https://www.deviqa.com/blog/10-steps-you-should-take-in-any-test-case-scenario/" rel="noopener noreferrer"&gt;How to write test cases&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.deviqa.com/blog/manual-test-cases-writing-hacks/" rel="noopener noreferrer"&gt;Manual Test Cases Writing Hacks&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test conduction and bug reporting
&lt;/h3&gt;

&lt;p&gt;After all test cases have been made up, and the test environment has been prepared, manual testers go ahead with test conduction. If manual testers detect bugs during testing, they must log bug reports using a bug tracking system. The bug reports must also be detailed and contain reproduction steps, an expected result, an actual result, and relevant attachments (screenshots, screen recording, etc.). Therefore, a developer can get bug essence right and quickly reproduce it.&lt;/p&gt;

&lt;p&gt;Related Article:&lt;br&gt;
&lt;a href="https://www.deviqa.com/blog/how-to-write-an-effective-software-defect-report/" rel="noopener noreferrer"&gt;How to write an effective software defect report&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Analysis of testing results
&lt;/h3&gt;

&lt;p&gt;As a rule, after testing completion, manual testers undertake an analysis to receive useful metrics that can help make the right consequences and plan future activities. It can take just a few clicks if you use one of the various test case management systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Manual Testing
&lt;/h2&gt;

&lt;p&gt;In our manual testing guide, we cannot leave out the manual testing types. Frankly speaking, there are countless manual testing types, but we will consider the most widely used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exploratory Testing
&lt;/h3&gt;

&lt;p&gt;Generally, manual testers turn to exploratory testing when they want to understand the basic idea of the software or get acquainted with its new features. It has no guidelines, and testers explore systems following their own initiative and curiosity. Exploratory testing is carried out whenever a tester thinks it is required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usability Testing
&lt;/h3&gt;

&lt;p&gt;There is no chance to effectively carry out usability testing without engaging people because the user-friendliness of software is evaluated on the ground of users behavior and emotions. During usability testing, manual testers make sure that an application is simple, convenient, and intuitive to avoid end-users confusion and frustration.&lt;/p&gt;

&lt;p&gt;Related article: &lt;a href="https://www.deviqa.com/blog/what-you-should-know-about-usability-testing/" rel="noopener noreferrer"&gt;What You Should Know About Usability Testing&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GUI testing
&lt;/h3&gt;

&lt;p&gt;In the process of GUI testing manual testers check fonts, color palette, windows, buttons, and all other GUI elements and characteristics to guarantee that there are no errors or confusions and provide the best user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Localization
&lt;/h3&gt;

&lt;p&gt;Manual testers perform localization testing to ensure that an application meets various language and cultural requirements. Localization testing is particularly important if an application is targeted at a global user community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compatibility testing
&lt;/h3&gt;

&lt;p&gt;Compatibility testing is conducted to ensure that an application works properly with other software, different hardware, network, etc. Compatibility testing is rather time-intensive. For this reason, most QA teams tend to automate this process. Still, if there is a need to carry it out manually, it is advised to define the top-priority browsers and platforms and concentrate on them.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://www.deviqa.com/blog/what-is-compatibility-testing/" rel="noopener noreferrer"&gt;What is compatibility testing&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Smoke Testing
&lt;/h3&gt;

&lt;p&gt;Smoke testing verifies only the key functionality of the application to define whether it corresponds to its primary objective and does not contain critical bugs. Smoke testing is a kind of preliminary checking that is carried out before more critical, in-depth testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regression Testing
&lt;/h3&gt;

&lt;p&gt;Regression testing is executed before every release to check whether updates have not affected existing functionalities. Regression testing of large, sophisticated applications can be extremely time-consuming. For this reason, if there are opportunities, many companies try to automate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Manual Testing Techniques
&lt;/h2&gt;

&lt;p&gt;Three manual testing techniques are differentiated. So, let's consider each of them one by one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Black box testing
&lt;/h3&gt;

&lt;p&gt;Black box testing is conducted in a way that resembles end-users interaction with a system. It doesn't require knowledge of the internal structure and coding skills. Conducting black-box testing, QA engineers interact with UI, test functionality, and verify whether outputs coincide with expected results.&lt;/p&gt;

&lt;h3&gt;
  
  
  White box testing
&lt;/h3&gt;

&lt;p&gt;White box testing technique is usually utilized by developers to review code and dataflows and detect possible hidden bugs. This technique requires good coding skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grey Box testing
&lt;/h3&gt;

&lt;p&gt;This manual testing technique is a balanced combination of either black box testing or white box testing. Grey box testing covers all aspects and deals with everything but in a more superficial manner.&lt;/p&gt;

&lt;p&gt;Related article: &lt;a href="https://www.deviqa.com/blog/difference-between-white-box-black-box-and-grey-box-testing/" rel="noopener noreferrer"&gt;Difference between white box, black box and grey box testing&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Myths of Manual Testing
&lt;/h2&gt;

&lt;p&gt;A manual tester profession appeared quite a long time ago, and a considerable number of myths have grown around it. Right now, we will debunk the most common myths.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual testing is easy
&lt;/h3&gt;

&lt;p&gt;It is probably the most widely spread myth. According to mainstream thinking, everybody can do testing. Let me disagree. Manual testing is a sort of art. A special mindset and skills are required to conduct testing as it is not just a random clicking, as some people may think. A manual tester must be extremely detail-oriented, obsessed with product quality, think extraordinary, know different software development aspects, and many others. Not everyone can be a professional manual tester.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual testing is out-of-date
&lt;/h3&gt;

&lt;p&gt;This misbelief is becoming very popular these days. Some people think that manual testing has become out-of-date, and automated testing will completely replace it very soon. We must reassure you that manual testing is the base of the QA process. Automated testing would never displace it. Manual testing helps make a stable product, and only after that, automated testing gets into a game. Automated testing is impossible without previous manual testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manque programmers choose the testing profession
&lt;/h3&gt;

&lt;p&gt;It's worth saying that not every programmer can become a good tester while many manual testers successfully master programming to understand all aspects of software operation and move to a new level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testers get down to work only on the post-development stage
&lt;/h3&gt;

&lt;p&gt;There is an opinion that manual testers idle most of the time and get to work in the end. It is a blunder. If some companies indeed use this approach, the project has severe problems. The involvement of a QA team at a final stage is a big risk for product quality and schedule. Testers must get to work as early as possible to have enough time to study documentation, analyze risks, draw up and conduct test cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importance of Manual Testing
&lt;/h2&gt;

&lt;p&gt;As was mentioned earlier, some people have doubts about the importance of manual testing. Nevertheless, any professional QA engineer can easily refute this statement. There are many reasons why manual testing is indispensable, so let's consider some of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Certain tests must be conducted only manually
&lt;/h3&gt;

&lt;p&gt;User experience plays an important role in quality assurance. In some situations, just a human can properly conduct certain tasks and provide an appropriate assessment. For instance, it is impossible to imagine the conduction of usability testing or localization testing without human involvement. Compatibility and interactions with mobile devices can't be checked with automated testing as well. Application performance during wi-fi turning off and turning on, simultaneous running with other apps, incoming calls or messages, etc. can be checked only by a human too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated testing only supports human testers
&lt;/h3&gt;

&lt;p&gt;Automated testing cannot substitute manual testing but can be and even must be effectively used in combination with it. While automated tests save time with repetitive tasks, manual testing efforts can concentrate on more creative work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Most bugs are hidden in unexpected places
&lt;/h3&gt;

&lt;p&gt;Even keeping up with the previously prepared test cases, manual testers can still uncover bugs in places they have not expected to find. That is very important. Testers detect many bugs while they are checking something else. In its turn, automated testing can't spot defects that it hasn't been programmed to search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automation is not budget-friendly for small-scale projects
&lt;/h3&gt;

&lt;p&gt;Automation requires not only considerable initial investments but also high maintenance expenses. For large scale projects, automation can be indeed beneficial in a long-term perspective. However, for small projects, automation is still a waste of either time or money.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automation often falls behind sprints
&lt;/h3&gt;

&lt;p&gt;Due to continuous script updating, it is difficult for automated testing to keep up with sprints. Only perfectly managed automation can manage to do this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual testers assess product from the end-users perspective
&lt;/h3&gt;

&lt;p&gt;Manual testers usually act as end-users, so they not only ensure correct work of application and help define new ways of product improvement with their pieces of advice and suggestions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repetition and variability are of great importance
&lt;/h3&gt;

&lt;p&gt;Repetition and variability are two characteristics of effective testing. Automated testing is appropriate for the repetitive testing process, but it's not enough. Manual testing, in its turn, can provide needed variability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top Manual Testing Tools List
&lt;/h2&gt;

&lt;p&gt;Manual testers have at their disposal various useful tools that considerably simplify the testing process. Here you can find the most widely used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Case Management Tools (TestRail, Zephyr, Practitest, TestLink)
&lt;/h3&gt;

&lt;p&gt;These tools are handy and used by manual testers to easily create, manage, update, and store test cases.&lt;/p&gt;

&lt;p&gt;Related article: &lt;a href="https://www.deviqa.com/blog/best-test-management-tools/" rel="noopener noreferrer"&gt;Best Test Management Tools&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bug Tracking Tools (Jira, Trello, Bugzilla, Mantis)
&lt;/h3&gt;

&lt;p&gt;Bug tracking solutions are indispensable helpers of manual testers. With their help, QA engineers create, modify, store and manage bug reports as well as get valuable statistics.&lt;/p&gt;

&lt;p&gt;Related Article: &lt;a href="https://www.deviqa.com/blog/best-bug-tracking-software/" rel="noopener noreferrer"&gt;Best Bug Tracking Tools&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross Browser Testing Tools (BrowserStack, Sauce Labs, Browser Shots)
&lt;/h3&gt;

&lt;p&gt;These tools help manual testers quickly verify whether the UI elements are rendered correctly across multiple browsers and how the code responds in each browser.&lt;/p&gt;

&lt;p&gt;Related Article: &lt;a href="https://www.deviqa.com/blog/best-cross-browser-testing-tools-in-2019-review/" rel="noopener noreferrer"&gt;Best Cross Browser Testing Tools&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screen Capture Tools (CloudApp, Loom, Skitch)
&lt;/h3&gt;

&lt;p&gt;Manual testers often have to attach images and videos to bug reports to describe an issue more precisely. These tools help to create needed images and screen recordings quickly.&lt;/p&gt;

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

&lt;p&gt;Manual testing involves much effort and can also take much time. Nevertheless, it is essential to ensure a high level of software quality. Automated testing provides fantastic opportunities, but despite its advantages, automated scripts can test just what they have been written to test, while manual testing is more adaptable and creative. A human tester can always find things that an automated test cannot. To gain the best results and guarantee the top-notch quality, QA teams must use a combination of either manual or automated testing, as they are two sides of the same coin.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qualityassurance</category>
      <category>manualtesting</category>
    </item>
    <item>
      <title>A Guide to automated testing for microservices</title>
      <dc:creator>Mike Ralduxin</dc:creator>
      <pubDate>Wed, 22 Apr 2020 08:47:01 +0000</pubDate>
      <link>https://dev.to/deviqa-solutions/a-guide-to-automated-testing-for-microservices-1pfo</link>
      <guid>https://dev.to/deviqa-solutions/a-guide-to-automated-testing-for-microservices-1pfo</guid>
      <description>&lt;p&gt;Today a lot of applications use microservice architecture, but what should we know and how we should test this type of software? In this article, we will consider basic theoretical concepts about CDC testing and testing tools that will be helpful.&lt;/p&gt;

&lt;p&gt;Microservices architecture - is a collection of small services and each service responsible for certain functionality and can be written by using different programming languages, approaches, and solutions. One of the main goals of microservices-based application it's define strong contracts between the various microservices.&lt;/p&gt;

&lt;p&gt;Consumer-driven contract testing (CDC) - is a technique that allows us to test each application in isolation. After executing consumer tests we get generated pact files that will be used for getting verification results during executing provider tests. As a result, we will have artifacts that will be placed in Pact-broker.&lt;/p&gt;

&lt;p&gt;Let’s familiarize ourselves with the main concepts from the official sources.&lt;br&gt;
&lt;a href="https://docs.pact.io/" rel="noopener noreferrer"&gt;Pact&lt;/a&gt; - is a code-first consumer-driven contract testing tool, and is generally used by developers and testers who code. In general, a contract is between a consumer (for example, a client that wants to receive some data) and a provider (for example, an API on a server that provides the data the client needs).&lt;br&gt;
&lt;a href="https://github.com/pact-foundation/pact_broker" rel="noopener noreferrer"&gt;Pact Broker&lt;/a&gt; - is an application for sharing for consumer driven contracts and verification results. It is optimized for use with "pacts" (contracts created by the Pact framework), but can be used for any type of contract that can be serialized to JSON. The Pact Broker is an open source tool that requires you to deploy, administer and host it yourself but also they provide plug-and-play option at &lt;a href="https://pactflow.io/" rel="noopener noreferrer"&gt;pactflow.io&lt;/a&gt;. &lt;br&gt;
&lt;a href="https://mochajs.org/" rel="noopener noreferrer"&gt;Mocha&lt;/a&gt; - is a feature-rich JavaScript test framework running on &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and in the browser, making asynchronous testing simple and fun. Mocha allows you to use any assertion library.&lt;br&gt;
&lt;a href="https://www.chaijs.com/" rel="noopener noreferrer"&gt;Chai&lt;/a&gt; - is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.&lt;br&gt;
&lt;a href="https://github.com/axios/axios" rel="noopener noreferrer"&gt;Axios&lt;/a&gt; - promise based HTTP client for the browser and node.js.&lt;/p&gt;
&lt;h2&gt;
  
  
  Simple example of CDC testing.
&lt;/h2&gt;

&lt;p&gt;Here is a code snippet from package.json where you can see all packages that will be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pact-foundation/pact&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^9.9.3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^0.19.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^3.5.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mocha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^5.1.1&lt;/span&gt;&lt;span class="dl"&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 1. Consumer tests.
&lt;/h3&gt;

&lt;p&gt;There are two different specs that will be describing TODO API - “&lt;a href="https://jsonplaceholder.typicode.com/" rel="noopener noreferrer"&gt;JSONPlaceholder&lt;/a&gt;” and USER API - “&lt;a href="https://reqres.in/" rel="noopener noreferrer"&gt;REQ | RES&lt;/a&gt;” . The first example you can see below. Second spec the same except the request and response objects.&lt;/p&gt;

&lt;p&gt;todoClient.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getUserById&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
       &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="nx"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;todo.spec.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Todo API&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockServerURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:1234&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="c1"&gt;// Create the Pact object to represent your provider&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&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;Pact&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mockserver-integration.log&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="na"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pacts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="na"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Consumer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Todo Provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;pactfileWriteMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;merge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;});&lt;/span&gt;

 &lt;span class="c1"&gt;// this is the response you expect from your Provider&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EXPECTED_BODY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delectus aut autem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
 &lt;span class="p"&gt;};&lt;/span&gt;

 &lt;span class="c1"&gt;// Start the mock server&lt;/span&gt;
 &lt;span class="nf"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

 &lt;span class="c1"&gt;// Write Pact when all tests done&lt;/span&gt;
 &lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finalize&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

 &lt;span class="c1"&gt;// verify with Pact, and reset expectations&lt;/span&gt;
 &lt;span class="nf"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

 &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Get todo by id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Get todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;uponReceiving&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A request for one todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;withRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/todos/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="na"&gt;willRespondWith&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json; charset=utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EXPECTED_BODY&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="c1"&gt;// add interactions to the Mock Server&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addInteraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;

   &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET /todos/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodoById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mockServerURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EXPECTED_BODY&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;After running tests we will receive the following pact files:&lt;br&gt;
consumer-user_provider.json&lt;br&gt;
consumer-todo_provider.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consumer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Consumer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Todo Provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;interactions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A request for one todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;providerState&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Get todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;request&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;method&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/todos/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Accept&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json; charset=utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delectus aut autem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metadata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pactSpecification&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2. Publishing pact files. In this example we will use &lt;a href="https://pactflow.io/" rel="noopener noreferrer"&gt;pactflow.io&lt;/a&gt; (Developer FREE plan).
&lt;/h3&gt;

&lt;p&gt;publish.pacts.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gitHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git rev-parse --short HEAD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;pactFilesOrDirs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pacts/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="na"&gt;pactBroker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourCompanyName.pact.dius.com.au&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;pactBrokerToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yourPactBrokerToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="na"&gt;consumerVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;gitHash&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;pact&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publishPacts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pact contract publishing complete!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pact contract publishing failed: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&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;For getting pactBrokerToken you need to proceed to /settings/api-tokens and copy Read/write token (CI)&lt;br&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%2Fi%2Fmggbcc54rupa1cuhpg0x.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%2Fi%2Fmggbcc54rupa1cuhpg0x.png" alt="proceed to /settings/api-tokens and copy Read/write token (CI)" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After running this script we will receive the following results:&lt;br&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%2Fi%2Flyzu5lkt3cnhzdunbqaj.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%2Fi%2Flyzu5lkt3cnhzdunbqaj.png" alt="the following results" width="800" height="160"&gt;&lt;/a&gt;&lt;br&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%2Fi%2Fkf9670q2nm2chjs5hvp3.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%2Fi%2Fkf9670q2nm2chjs5hvp3.png" alt="the following results" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3. Pacts Verification
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INFO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;providerVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;pactBrokerUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourCompanyName.pact.dius.com.au&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;pactBrokerToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yourPactBrokerToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;publishVerificationResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pacts Verification&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Validates the expectations of Todo provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;new&lt;/span&gt; &lt;span class="nc"&gt;Verifier&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
           &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Todo Provider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;providerBaseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;verifyProvider&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;

   &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Validates the expectations of User provider &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;new&lt;/span&gt; &lt;span class="nc"&gt;Verifier&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
           &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User Provider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;providerBaseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://reqres.in/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;verifyProvider&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;After running tests we will receive the following results:&lt;br&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%2Fi%2F2osk0oonkdddocerklek.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%2Fi%2F2osk0oonkdddocerklek.png" alt="the following results" width="800" height="157"&gt;&lt;/a&gt;&lt;br&gt;
VIEW PACT:&lt;br&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%2Fi%2Fl6jdueqfsdnptejnxvrv.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%2Fi%2Fl6jdueqfsdnptejnxvrv.png" alt="VIEW PACT" width="800" height="343"&gt;&lt;/a&gt;&lt;br&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%2Fi%2Fwcottyf6ymutf2rkyn1f.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%2Fi%2Fwcottyf6ymutf2rkyn1f.png" alt="VIEW PACT" width="800" height="331"&gt;&lt;/a&gt;&lt;br&gt;
Let’s change the title in the expected result &lt;strong&gt;from step 1&lt;/strong&gt; for simulating an error.&lt;/p&gt;

&lt;p&gt;Previous object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EXPECTED_BODY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delectus aut autem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
 &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EXPECTED_BODY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Our new title that will trigger the error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
 &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result after running tests:&lt;br&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%2Fi%2F4i86mnoz7efown60jvgg.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%2Fi%2F4i86mnoz7efown60jvgg.png" alt="Result after running tests" width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Console output:&lt;br&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%2Fi%2F874q3drfw20lonmac79k.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%2Fi%2F874q3drfw20lonmac79k.png" alt="Console output" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions.
&lt;/h2&gt;

&lt;p&gt;Testing microservices it's a very difficult process that requires a good knowledge of different testing tools for achieving needed goals. In this article, we considered basic concepts and simple example of writing CDC tests using Pact. You can deeply familiarize yourself with this powerful testing tool on the official site and use all provided features for testing your microservices.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>microservices</category>
      <category>automation</category>
      <category>guide</category>
    </item>
  </channel>
</rss>
