<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Malith Senadheera on Medium]]></title>
        <description><![CDATA[Stories by Malith Senadheera on Medium]]></description>
        <link>https://medium.com/@malitthh?source=rss-1158dabec505------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*vXMCC_M8XgmK6Wz9x5S_3w.png</url>
            <title>Stories by Malith Senadheera on Medium</title>
            <link>https://medium.com/@malitthh?source=rss-1158dabec505------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 15 Apr 2026 03:29:21 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@malitthh/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Kickstarting Mobile Test Automation with Appium.]]></title>
            <link>https://blog.stackademic.com/kickstarting-mobile-test-automation-with-appium-c8e41f54e39c?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/c8e41f54e39c</guid>
            <category><![CDATA[appium]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[mobile-test-automation]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Sat, 13 Sep 2025 12:13:25 GMT</pubDate>
            <atom:updated>2026-02-25T08:05:26.600Z</atom:updated>
            <content:encoded><![CDATA[<p>Mobile applications have become an integral part of our daily lives, and ensuring their quality is more important than ever.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bvz8Cv08YA7KrhtIq0B94w.jpeg" /></figure><p>As testers and developers, we need reliable tools to automate testing across different platforms. In this article, we’ll take a closer look at how you can get started with Appium to build your first automated tests.</p><p>🔸<strong>Understanding Appium</strong></p><ul><li><strong>What is Appium? — </strong>Appium is a open-source project &amp; eco system of related software designed to facilitate UI automation of many different platform. e.g., Mobile Apps (iOS, Android), Desktop Apps &amp; Web.</li><li>Its a Node.js program and built on top of WebDriver (Selenium — The goal of the Selenium project has been to support UI automation of web browsers) &amp; support automation code written in many different languages (Java, JavaScript, Python).</li><li>In order to achieve this, Appium is effectively split into four parts,</li></ul><ol><li><strong>Appium Core —</strong> defines the core APIs</li><li><strong>Drivers —</strong> implement connectivity to specific platforms</li><li><strong>Clients —</strong> implement Appium’s API in specific languages</li><li><strong>Plugins —</strong> change or extend Appium’s core functionality</li></ol><p>Most software interfaces tend to share similar structures. As a result, the WebDriver specification offers automation API fundamentals , such as locating elements, interacting with them, and navigating pages or screens, that generally correspond across different platforms.</p><ul><li><strong>Platform Automation Behavior — </strong>The Appium driver takes care of this role, it’s an independent, plug-in module that enables Appium to automate a specific platform.</li><li>End goal is to simply implement Appium’s internal interfaces that correspond to the WebDriver protocol. How each driver fulfills this implementation is entirely up to it.</li><li>e.g., Apple maintains an iOS automation technology called XCUI Test -&gt; Appium support iOS app automation is called XCUITest Driver -&gt; convert the WebDriver protocol to XCUITest Library calls.</li><li><strong>Universal programming language access — </strong>One of the key advantages of the client-server architecture is that it keeps the automation executor (the server, which performs the actions) separate from the automation controller (the client, which specifies what actions should be carried out and in what order).</li><li>In other words, you can relatively easily make basic Appium or WebDriver features available in a new programming language, as long as it supports high-level HTTP libraries, this only requires implementing a simple HTTP client in that language.</li><li><strong>Client-Server Architecture in Appium</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5IGFwFRk78RJQI9eDY4LNA.png" /><figcaption>Mind Map — Client-Server Architecture</figcaption></figure><ul><li><strong>Appium Clients — </strong>The test code you write, created by the test author, sends commands to the Appium server and receives the response.</li><li>Clients are maintained separately. Having a good set of helper functions in one client doesn’t guarantee the same in another. Some clients receive updates more regularly.</li></ul><pre>WebElement element = driver.findElement(By.Xpath(&quot;//*[@text=&#39;Test&#39;]&quot;))<br>element.click()<br>System.out.println(element.getText())<br>System.out.println(driver.getPageSource())</pre><ul><li><strong>Appium Drivers — </strong>In the simplest terms, a driver is a Node.js class that derives from Appium’s “BaseDriver” class.</li></ul><pre>import BaseDriver from &#39;@appium/base-driver&#39;<br><br>class MyDriver extends BaseDriver {<br>}</pre><p>Technically, an Appium driver is simply code that extends other Appium code. By inheriting from “BaseDriver”, it gains a lot, “BaseDriver” is essentially an encapsulation of the entire WebDriver protocol.</p><p><strong>🔸Getting Started with Appium + Java</strong></p><blockquote><strong>1. Install basics (Pick your OS: Windows/macOS)</strong></blockquote><p>Essentials: Java JDK, Node.js, Android Studio (SDK + Emulator), You can also install Appium desktop/GUI, but CLI is recommended.</p><pre>//install Appium, It doesn&#39;t come bundled with any drivers.<br>npm install -g appium<br><br>//check Appium version.<br>appium -v &amp; where appium <br><br>//After installing Appium, install UiAutomator2 or XCUITest Drivers, <br>//before installing, make sure Appium server is not running (quit via Ctrl+C). <br>appium driver install uiautomator2 or appium driver install xcuitest<br><br>//install multiple drivers.<br>appium setup<br><br>//Validating the Install.<br>appium driver doctor uiautomator2 <br><br>//Verify adb (Android Debug Bridge) is available.<br>//It’s a CLI tool that lets your computer communicate with Android devices (real or emulator).<br>adb devices<br><br>//Start Appium Server<br>appium<br><br>//--allow-cors is a flag for Appium that enables Cross-Origin Resource Sharing (CORS), allowing testing frameworks or tools (like Appium Inspector) running on a different domain than the Appium server to communicate with it.<br>appium --allow-cors<br><br>//Fix Appium installation issues by reinstalling a fresh latest version,<br>//-g means it was installed system-wide, not just inside a project.<br>npm uninstall -g appium<br>npm cache clean --force<br>npm install -g appium@latest</pre><blockquote><strong>2. Set up Android automation requirements</strong></blockquote><p>▫️Android SDK</p><p>The simplest way to configure the Android SDK requirements is to install <a href="https://developer.android.com/studio">Android Studio</a>. Using its SDK Manager (Settings → Appearance &amp; Behavior → System Settings → Android SDK), we can download:</p><ul><li>Android SDK Platform (choose the Android platform you want to automate, e.g., API level 30)</li><li>Android SDK Platform-Tools</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JsrGzy4TGnD8Q5iT3VUfFQ.png" /><figcaption>Android SDK Platform &amp; Tools</figcaption></figure><ul><li>Set up the ANDROID_HOME environment variable to point to the directory where the Android SDK is installed.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f3c2ah-TIZhYfvwEaHBQ_A.png" /><figcaption>ANDROID_HOME — Env Variable Path</figcaption></figure><p>▫️Java JDK</p><p>Install the Java JDK, You can download this from <a href="https://jdk.java.net/">Oracle</a>.</p><ul><li>Set up the JAVA_HOME environment variable to point to the JDK home directory</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qeqL_Ttut4JvVqiZRRbpmw.png" /><figcaption>JAVA_HOME — Env Variable Path</figcaption></figure><p>▫️Prepare the Device</p><p>If you’re using an emulator, create and launch an Android Virtual Device (AVD) through Android Studio. If you’re using a physical device, configure it for development and enable USB Debugging.</p><ul><li>Once the emulator or device is connected, run “adb devices” (found under $ANDROID_HOME/platform-tools/adb) to confirm that it is detected.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gTCnsaKWtoV-5AUmbqtcHw.png" /><figcaption>adb_devices — Env Variable Path</figcaption></figure><p>At this point, everything should be ready to go. If problems arise, refer to the driver docs or the official Android/Java documentation.</p><blockquote><strong>3. Starting with Appium</strong></blockquote><p><strong>Step 1: Create a Maven Project</strong></p><p>You can do this in “IntelliJ IDEA” or “Eclipse”. This creates a pom.xml and a src folder.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/507/1*2BxmL5sKs_gd2vNTtfoUbQ.png" /><figcaption>Appium Sample Framework</figcaption></figure><p><strong>Step 2: Add Dependencies in </strong>pom.xml</p><pre>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;<br> xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;<br> xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;<br> &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;<br><br> &lt;groupId&gt;com.example&lt;/groupId&gt;<br> &lt;artifactId&gt;Appium-Automation&lt;/artifactId&gt;<br> &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;<br><br> &lt;properties&gt;<br>  &lt;maven.compiler.source&gt;17&lt;/maven.compiler.source&gt;<br>  &lt;maven.compiler.target&gt;17&lt;/maven.compiler.target&gt;<br>  &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;<br> &lt;/properties&gt;<br><br> &lt;dependencies&gt;<br>  &lt;!-- Selenium Java --&gt;<br>  &lt;dependency&gt;<br>   &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>   &lt;artifactId&gt;selenium-java&lt;/artifactId&gt;<br>   &lt;version&gt;4.15.0&lt;/version&gt;<br>  &lt;/dependency&gt;<br><br>  &lt;!-- Appium Java client --&gt;<br>  &lt;dependency&gt;<br>   &lt;groupId&gt;io.appium&lt;/groupId&gt;<br>   &lt;artifactId&gt;java-client&lt;/artifactId&gt;<br>   &lt;version&gt;9.0.0&lt;/version&gt;<br>   &lt;exclusions&gt;<br>    &lt;!-- Exclude any unwanted Selenium dependencies --&gt;<br>    &lt;exclusion&gt;<br>     &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>     &lt;artifactId&gt;selenium-java&lt;/artifactId&gt;<br>    &lt;/exclusion&gt;<br>    &lt;exclusion&gt;<br>     &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>     &lt;artifactId&gt;selenium-api&lt;/artifactId&gt;<br>    &lt;/exclusion&gt;<br>    &lt;exclusion&gt;<br>     &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>     &lt;artifactId&gt;selenium-os&lt;/artifactId&gt;<br>    &lt;/exclusion&gt;<br>   &lt;/exclusions&gt;<br>  &lt;/dependency&gt;<br><br>  &lt;!-- TestNG --&gt;<br>  &lt;dependency&gt;<br>   &lt;groupId&gt;org.testng&lt;/groupId&gt;<br>   &lt;artifactId&gt;testng&lt;/artifactId&gt;<br>   &lt;version&gt;7.8.0&lt;/version&gt;<br>   &lt;scope&gt;test&lt;/scope&gt;<br>  &lt;/dependency&gt;<br><br>  &lt;!-- SLF4J simple logger (optional, removes warning messages) --&gt;<br>  &lt;dependency&gt;<br>   &lt;groupId&gt;org.slf4j&lt;/groupId&gt;<br>   &lt;artifactId&gt;slf4j-simple&lt;/artifactId&gt;<br>   &lt;version&gt;2.0.9&lt;/version&gt;<br>  &lt;/dependency&gt;<br> &lt;/dependencies&gt;<br><br> &lt;build&gt;<br>  &lt;plugins&gt;<br>   &lt;!-- Maven Surefire Plugin for TestNG --&gt;<br>   &lt;plugin&gt;<br>    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br>    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;<br>    &lt;version&gt;2.22.2&lt;/version&gt;<br>    &lt;configuration&gt;<br>     &lt;suiteXmlFiles&gt;<br>      &lt;suiteXmlFile&gt;testng.xml&lt;/suiteXmlFile&gt;<br>     &lt;/suiteXmlFiles&gt;<br>    &lt;/configuration&gt;<br>   &lt;/plugin&gt;<br>  &lt;/plugins&gt;<br> &lt;/build&gt;<br>&lt;/project&gt;</pre><p><strong>Step 3: Start Appium Server</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tKzzsWVJg8tOc0XaAHo8CQ.png" /></figure><p><strong>Step 4: Download prebuilt APK directly</strong></p><ul><li>What is an APK? — APK stands for Android Package Kit, the file format used to install and distribute apps on Android devices.</li><li>e.g., Android apps: *.apk , iOS apps: *.app (for simulators) &amp; *.ipa (for real devices)</li><li>An APK is essentially a package that contains everything an app needs to work properly:</li><li>The app’s instructions (code)</li><li>Visual elements (images, icons, UI)</li><li>Audio and other media (sounds, videos)</li><li>It ensures that the app can be installed and run smoothly on an Android device.</li><li>Appium provides it here: <a href="https://github.com/appium/android-apidemos/releases">ApiDemos-debug.apk (direct link)</a> or <a href="https://github.com/saucelabs/sample-app-mobile/releases">https://github.com/saucelabs/sample-app-mobile/releases</a></li><li>Save it into your project at: src/test/resources/apps/ApiDemos-debug.apk</li></ul><pre>//Add aapt to your PATH<br>C:\Users\UserName\AppData\Local\Android\Sdk\build-tools\34.0.1<br><br>//quick way to find &#39;appPackage&#39; and &#39;appActivity&#39; for any APK so you don’t have to guess<br>aapt dump badging D:/Learning/Source/Repos/Appium-Automation/src/test/resources/apps/Android.SauceLabs.Mobile.Sample.app.2.7.1.apk</pre><p><strong>Step 5: Write Your First Test (Android Example)</strong></p><pre>package com.appium.utils;<br><br>import java.net.MalformedURLException;<br>import java.net.URL;<br>import java.time.Duration;<br><br>import io.appium.java_client.AppiumDriver;<br>import io.appium.java_client.android.AndroidDriver;<br>import io.appium.java_client.android.options.UiAutomator2Options;<br>import io.appium.java_client.service.local.AppiumDriverLocalService;<br>import io.appium.java_client.service.local.AppiumServiceBuilder;<br><br>public class DriverFactory {<br><br>    private static AppiumDriver driver;<br>    private static AppiumDriverLocalService service;<br><br>    public static AppiumDriver getDriver() throws MalformedURLException {<br>        if (driver == null) {<br><br>            // Load config<br>            ConfigReader.loadProperties();<br><br>            // Start Appium server programmatically (optional)<br>            if (ConfigReader.get(&quot;startAppiumServer&quot;).equalsIgnoreCase(&quot;true&quot;)) {<br>                service = new AppiumServiceBuilder().usingAnyFreePort().build();<br>                service.start();<br>            }<br><br>            // Setup capabilities from config<br>            UiAutomator2Options options = new UiAutomator2Options()<br>                    .setPlatformName(ConfigReader.get(&quot;platformName&quot;))<br>                    .setDeviceName(ConfigReader.get(&quot;deviceName&quot;))<br>                    .setAutomationName(ConfigReader.get(&quot;automationName&quot;))<br>                    .setAppPackage(ConfigReader.get(&quot;appPackage&quot;))<br>                    .setAppActivity(ConfigReader.get(&quot;appActivity&quot;))<br>                    .setApp(System.getProperty(&quot;user.dir&quot;) + &quot;/&quot; + ConfigReader.get(&quot;app&quot;))<br>                    .setNewCommandTimeout(Duration.ofSeconds(Long.parseLong(ConfigReader.get(&quot;newCommandTimeout&quot;))));<br><br>            URL serverURL = new URL(ConfigReader.get(&quot;appiumServerURL&quot;));<br>            driver = new AndroidDriver(serverURL, options);<br>        }<br>        return driver;<br>    }<br><br>    public static void quitDriver() {<br>        if (driver != null) {<br>            driver.quit();<br>            driver = null;<br>        }<br>        if (service != null) {<br>            service.stop();<br>            service = null;<br>        }<br>    }<br>}</pre><pre>package com.appium.tests;<br><br>import com.appium.pages.LoginPage;<br>import com.appium.utils.DriverFactory;<br>import com.appium.utils.ConfigReader;<br>import io.appium.java_client.AppiumDriver;<br>import org.testng.annotations.BeforeMethod;<br>import org.testng.annotations.AfterMethod;<br><br>import java.io.IOException;<br><br>public class BaseTest {<br><br>    protected AppiumDriver driver;<br><br>    @BeforeMethod<br>    public void setUp() throws IOException {<br>        // Load config<br>        ConfigReader.loadProperties();<br><br>        // Initialize driver<br>        driver = DriverFactory.getDriver();<br><br>        // Login automatically if login page is visible<br>        LoginPage loginPage = new LoginPage(driver);<br>        if (loginPage.isLoginPageVisible()) {<br>            String username = ConfigReader.get(&quot;valid.username&quot;);<br>            String password = ConfigReader.get(&quot;valid.password&quot;);<br>            loginPage.login(username, password);<br>        }<br>    }<br><br>    @AfterMethod<br>    public void tearDown() {<br>        DriverFactory.quitDriver();<br>    }<br>}</pre><pre>package com.appium.pages;<br><br>import java.time.Duration;<br>import org.openqa.selenium.By;<br>import org.openqa.selenium.WebElement;<br>import org.openqa.selenium.support.ui.ExpectedConditions;<br>import org.openqa.selenium.support.ui.WebDriverWait;<br><br>import io.appium.java_client.AppiumBy;<br>import io.appium.java_client.AppiumDriver;<br><br>public class LoginPage {<br>    private final AppiumDriver driver;<br>    private final WebDriverWait wait;<br><br>    public LoginPage(AppiumDriver driver) {<br>        this.driver = driver;<br>        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));<br>    }<br><br>    private final By usernameField = AppiumBy.accessibilityId(&quot;test-Username&quot;);<br>    private final By passwordField = AppiumBy.accessibilityId(&quot;test-Password&quot;);<br>    private final By loginBtn = AppiumBy.accessibilityId(&quot;test-LOGIN&quot;);<br>    private final By errorMsg = AppiumBy.xpath(<br>            &quot;//android.widget.TextView[@text=\&quot;Username and password do not match any user in this service.\&quot;]&quot;);<br><br>    public void enterUsername(String username) {<br>        WebElement user = wait.until(ExpectedConditions.visibilityOfElementLocated(usernameField));<br>        user.clear();<br>        user.sendKeys(username);<br>    }<br><br>    public void enterPassword(String password) {<br>        WebElement pass = wait.until(ExpectedConditions.visibilityOfElementLocated(passwordField));<br>        pass.clear();<br>        pass.sendKeys(password);<br>    }<br><br>    public void tapLogin() {<br>        WebElement button = wait.until(ExpectedConditions.elementToBeClickable(loginBtn));<br>        button.click();<br>    }<br><br>    public void login(String username, String password) {<br>        enterUsername(username);<br>        enterPassword(password);<br>        tapLogin();<br>    }<br><br>    public String getErrorMessage() {<br>        WebElement msg = wait.until(ExpectedConditions.visibilityOfElementLocated(errorMsg));<br>        return msg.getText();<br>    }<br><br>    public boolean isLoginPageVisible() {<br>        try {<br>            return wait.until(ExpectedConditions.visibilityOfElementLocated(usernameField)).isDisplayed();<br>        } catch (Exception e) {<br>            return false;<br>        }<br>    }<br>}</pre><pre>package com.appium.pages;<br><br>import com.appium.utils.ConfigReader;<br>import io.appium.java_client.AppiumBy;<br>import io.appium.java_client.AppiumDriver;<br><br>import org.openqa.selenium.By;<br>import org.openqa.selenium.WebElement;<br>import org.openqa.selenium.support.ui.ExpectedConditions;<br>import org.openqa.selenium.support.ui.WebDriverWait;<br><br>import java.time.Duration;<br>import java.util.List;<br><br>public class HomePage {<br><br> private final AppiumDriver driver;<br> private final WebDriverWait wait;<br><br> public HomePage(AppiumDriver driver) {<br>  this.driver = driver;<br>  this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));<br> }<br><br> private final By homePageTitle = AppiumBy.xpath(&quot;//android.widget.TextView[@text=&#39;PRODUCTS&#39;]&quot;);<br> private final By productTitles = AppiumBy.xpath(&quot;//android.widget.TextView[@content-desc=&#39;test-Item title&#39;]&quot;);<br> private final By toggleIcons = AppiumBy<br>   .xpath(&quot;//android.view.ViewGroup[@content-desc=&#39;test-Toggle&#39;]/android.widget.ImageView&quot;);<br> private final By addButtons1 = AppiumBy.xpath(&quot;(//android.widget.TextView[@text=\&quot;+\&quot;])[1]&quot;);<br> private final By addButtons2 = AppiumBy.xpath(&quot;(//android.widget.TextView[@text=\&quot;+\&quot;])[2]&quot;);<br> private final By removeButtons = AppiumBy.xpath(&quot;//android.widget.TextView[@text=\&quot;-\&quot;]&quot;);<br> private final By filterButton = AppiumBy.xpath(<br>   &quot;//android.view.ViewGroup[@content-desc=&#39;test-Modal Selector Button&#39;]/android.view.ViewGroup/android.view.ViewGroup/android.widget.ImageView&quot;);<br> private final By sortPriceLowToHigh = AppiumBy.xpath(&quot;//android.widget.TextView[@text=&#39;Price (low to high)&#39;]&quot;);<br><br> // --- Page checks ---<br> public boolean isPageLoaded() {<br>  return wait.until(ExpectedConditions.visibilityOfElementLocated(homePageTitle)).isDisplayed();<br> }<br><br> // --- Product list ---<br> public List&lt;WebElement&gt; getProductTitles() {<br>  return wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(productTitles));<br> }<br><br> // --- Actions ---<br> public void tapToggleIcon() {<br>  wait.until(ExpectedConditions.visibilityOfElementLocated(toggleIcons)).click();<br> }<br><br> public void tapFirstAddButton() {<br>  wait.until(ExpectedConditions.visibilityOfElementLocated(addButtons1)).click();<br> }<br><br> public void tapSecondAddButton() {<br>  wait.until(ExpectedConditions.visibilityOfElementLocated(addButtons2)).click();<br> }<br><br> public void tapFirstRemoveButton() {<br>  wait.until(ExpectedConditions.visibilityOfElementLocated(removeButtons)).click();<br> }<br><br> public void tapFilterButton() {<br>  wait.until(ExpectedConditions.elementToBeClickable(filterButton)).click();<br> }<br><br> public void tapSortPriceLowToHigh() {<br>  wait.until(ExpectedConditions.elementToBeClickable(sortPriceLowToHigh)).click();<br> }<br><br> // --- Scroll and select product ---<br> public void scrollToProductAndSelect(String productName) {<br>  String uiScroll = String.format(<br>    &quot;new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\&quot;%s\&quot;))&quot;,<br>    productName);<br>  driver.findElement(AppiumBy.androidUIAutomator(uiScroll));<br>  driver.findElement(AppiumBy.androidUIAutomator(String.format(&quot;new UiSelector().text(\&quot;%s\&quot;)&quot;, productName)))<br>    .click();<br> }<br>}</pre><pre>package com.appium.tests;<br><br>import com.appium.pages.HomePage;<br>import io.appium.java_client.AppiumBy;<br>import io.appium.java_client.AppiumDriver;<br>import org.openqa.selenium.WebElement;<br>import org.openqa.selenium.support.ui.ExpectedConditions;<br>import org.openqa.selenium.support.ui.WebDriverWait;<br>import org.testng.Assert;<br>import org.testng.annotations.Test;<br><br>import java.time.Duration;<br>import java.util.List;<br><br>public class HomePageTest extends BaseTest {<br><br>    private HomePage homePage;<br><br>    @Test(priority = 1)<br>    public void testGetAllTitlesAndSelectOnesie() {<br>        homePage = new HomePage(driver);<br>        Assert.assertTrue(homePage.isPageLoaded(), &quot;Home page did not load.&quot;);<br><br>        List&lt;WebElement&gt; titles = homePage.getProductTitles();<br>        Assert.assertFalse(titles.isEmpty(), &quot;No product titles found on home page.&quot;);<br><br>        System.out.println(&quot;Products visible on screen:&quot;);<br>        for (WebElement title : titles) {<br>            String text = title.getText();<br>            System.out.println(&quot; - &quot; + text);<br>            Assert.assertFalse(text.isEmpty(), &quot;Product title should not be empty&quot;);<br>            Assert.assertTrue(title.isDisplayed(), &quot;Product title should be visible&quot;);<br>        }<br>    }<br><br>    @Test(priority = 2)<br>    public void testTapAllHomePageActions() {<br>        homePage = new HomePage(driver);<br>        Assert.assertTrue(homePage.isPageLoaded(), &quot;Home page did not load.&quot;);<br><br>        homePage.tapToggleIcon();<br>        homePage.tapFirstAddButton();<br>        Assert.assertFalse(driver.findElements(AppiumBy.xpath(&quot;//android.widget.TextView[@text=&#39;-&#39;]&quot;)).isEmpty(),<br>                &quot;Remove button should appear after adding product&quot;);<br>        homePage.tapSecondAddButton();<br>        homePage.tapFirstRemoveButton();<br><br>        homePage.tapFilterButton();<br>        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));<br>        Assert.assertTrue(wait.until(ExpectedConditions.visibilityOfElementLocated(<br>                        AppiumBy.xpath(&quot;//android.widget.FrameLayout[@resource-id=&#39;android:id/content&#39;]//android.view.ViewGroup[1]&quot;)))<br>                .isDisplayed(),<br>                &quot;Filter modal should be visible after tapping filter button&quot;);<br><br>        homePage.tapSortPriceLowToHigh();<br>        homePage.tapToggleIcon();<br>    }<br><br>    @Test(priority = 3)<br>    public void selectTheItems() {<br>        homePage = new HomePage(driver);<br>        homePage.scrollToProductAndSelect(&quot;Sauce Labs Onesie&quot;);<br><br>        String productTitle = driver.findElement(AppiumBy.xpath(&quot;//android.widget.TextView[@text=&#39;Sauce Labs Onesie&#39;]&quot;)).getText();<br>        Assert.assertEquals(productTitle, &quot;Sauce Labs Onesie&quot;, &quot;Wrong product opened after scroll.&quot;);<br>    }<br>}</pre><p><strong>Step 6: Run the Test</strong></p><pre>//Add Emulator to PATH<br>C:\Users\&lt;YourUser&gt;\AppData\Local\Android\Sdk\emulator<br><br>//To use Emulator<br>emulator -list-avds<br>emulator -avd Medium_Phone_API_36.0<br><br>//To start AVD in a new state<br>emulator -avd Medium_Phone_API_36.0 -no-snapshot-load<br><br>//Get the Android version of your device or emulator<br>adb shell getprop ro.build.version.release </pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DOhXqtOHw3Ca_RS-AZXZ1g.png" /><figcaption>Run As -&gt; Maven Build or Maven Install</figcaption></figure><blockquote><strong>4. How to setup and use Appium Inspector</strong></blockquote><p>Appium Inspector is a GUI tool used for inspecting mobile apps (both Android and iOS) in the context of automation testing. It allows testers and developers to interact with the app’s UI elements, understand their properties, and generate the necessary locators for writing automation scripts in Appium.</p><p>Download and install Appium Inspector: <a href="https://github.com/appium/appium-inspector/releases">https://github.com/appium/appium-inspector/releases</a></p><ul><li>Typical Use Case</li></ul><ol><li>Before writing your automation script in Appium, you open the Appium Inspector.</li><li>Connect it to a real device or emulator/simulator.</li><li>Navigate through the app in the inspector to identify elements and understand their properties.</li><li>Copy the locators into your test scripts.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P7AFjCNYu2AeIUtLdRKdPg.png" /><figcaption>Appium Inspector — Capability Builder</figcaption></figure><pre>{<br>  &quot;appium:automationName&quot;: &quot;UiAutomator2&quot;,<br>  &quot;appium:platformName&quot;: &quot;Android&quot;,<br>  &quot;appium:platformVersion&quot;: &quot;16&quot;,<br>  &quot;appium:appPackage&quot;: &quot;com.swaglabsmobileapp&quot;,<br>  &quot;appium:appActivity&quot;: &quot;com.swaglabsmobileapp.MainActivity&quot;,<br>  &quot;appium:deviceName&quot;: &quot;Medium_Phone_API_36.0&quot;,<br>  &quot;appium:app&quot;: &quot;D:/Learning/Source/Repos/Appium-Automation/src/test/resources/apps/Android.SauceLabs.Mobile.Sample.app.2.7.1.apk&quot;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*67s1dBhbwyJ-P9V-_0LOAA.png" /><figcaption>Appium Inspector UI</figcaption></figure><p><a href="https://appium.io/docs/en/latest/intro/">https://appium.io/docs/en/latest/intro/</a> — Appium Documentation</p><p><a href="https://docs.saucelabs.com/mobile-apps/automated-testing/appium/configuration/">https://docs.saucelabs.com/mobile-apps/automated-testing/appium/configuration/</a> — SauceLabs Documentation</p><p><a href="https://testautomationu.applitools.com/appium-java-tutorial-1/">https://testautomationu.applitools.com/appium-java-tutorial-1/</a> — Mobile Testing with Appium and Java By <a href="https://medium.com/u/22507dab7991">Moataz Nabil</a></p><p><strong>Conclusion</strong></p><p>Appium is a versatile and powerful tool for automating mobile application testing across Android and iOS platforms. Its support for multiple programming languages, seamless integration with testing frameworks, and ability to interact with real devices and emulators make it an invaluable choice for QA engineers and developers.</p><p>By mastering Appium, you can efficiently create, maintain, and execute automated tests, ensuring the quality, reliability, and smooth performance of your mobile applications. This ultimately helps deliver a seamless user experience, reduces manual testing effort, and accelerates the release of high-quality apps.</p><p>You’ve reached the end of the article. Here’s a sample project to begin your journey with Appium. Try cloning this repository to your machine, learn, and contribute to the open-source community.</p><p><a href="https://github.com/Malitthh/Appium-Automation.git">https://github.com/Malitthh/Appium-Automation.git</a></p><p>Happy testing!</p><h3>A message from our Founder</h3><p><strong>Hey, </strong><a href="https://linkedin.com/in/sunilsandhu"><strong>Sunil</strong></a><strong> here.</strong> I wanted to take a moment to thank you for reading until the end and for being a part of this community.</p><p>Did you know that our team run these publications as a volunteer effort to over 3.5m monthly readers? <strong>We don’t receive any funding, we do this to support the community. ❤️</strong></p><p>If you want to show some love, please take a moment to <strong>follow me on </strong><a href="https://linkedin.com/in/sunilsandhu"><strong>LinkedIn</strong></a><strong>, </strong><a href="https://tiktok.com/@messyfounder"><strong>TikTok</strong></a>, <a href="https://instagram.com/sunilsandhu"><strong>Instagram</strong></a>. You can also subscribe to our <a href="https://newsletter.plainenglish.io/"><strong>weekly newsletter</strong></a>.</p><p>And before you go, don’t forget to <strong>clap</strong> and <strong>follow</strong> the writer️!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c8e41f54e39c" width="1" height="1" alt=""><hr><p><a href="https://blog.stackademic.com/kickstarting-mobile-test-automation-with-appium-c8e41f54e39c">Kickstarting Mobile Test Automation with Appium.</a> was originally published in <a href="https://blog.stackademic.com">Stackademic</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Git Story: Everything You Need to Know.]]></title>
            <link>https://medium.com/@malitthh/git-for-beginners-everything-you-need-to-know-0a1a79a7d522?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/0a1a79a7d522</guid>
            <category><![CDATA[gi̇t]]></category>
            <category><![CDATA[test-automation]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Tue, 11 Mar 2025 05:36:17 GMT</pubDate>
            <atom:updated>2026-02-12T17:26:55.920Z</atom:updated>
            <content:encoded><![CDATA[<p>By the end of this Article, you will know the purpose of Git, why it is useful, and be ready to start using it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fESLv7GAXBlfd2J1jGshmg.jpeg" /></figure><p>In the world of software development, managing code changes efficiently is crucial. Whether you’re working alone or collaborating with a team, keeping track of modifications, reverting mistakes, and maintaining different versions of your project can be challenging. This is where <strong>Git</strong>, a powerful <strong>Distributed Version Control System (DVCS)</strong>, comes into play.</p><p><strong>💠 Understanding Version Control</strong></p><ul><li><strong>What is Version Control? — </strong>Version control is a system that tracks changes to files over time, allowing you to access and restore previous versions when needed. It is essential for managing code, documents, and collaborative projects efficiently.</li></ul><ol><li><strong>Local Version Control — </strong>A common but unreliable approach to version control is manually copying files into separate directories, sometimes with timestamps. While simple, this method is prone to errors, such as overwriting or losing important changes.</li><li><strong>Centralized Version Control (CVCS) — </strong>To enable collaboration, Centralized Version Control Systems (CVCS), like CVS and Subversion, were introduced. These systems store all versioned files on a central server, allowing multiple users to check out and modify files. However, they depend on a single point of failure — if the server crashes, valuable data can be lost.</li><li><strong>Distributed Version Control (DVCS) — </strong>Distributed systems like Git solve this issue by allowing every user to maintain a complete copy of the repository, including its entire history. This means that even if the central server fails, the data can be restored from any local copy, ensuring better reliability and redundancy.</li></ol><p><strong>💠 A Brief History of Git</strong></p><p>Necessity often drives innovation, and Git is a prime example. Before its creation, the Linux kernel project managed changes manually through patches and archived files. In 2002, they adopted BitKeeper, a proprietary version control system that simplified collaboration.</p><p>However, in 2005, BitKeeper revoked free access due to disputes with the Linux community, leaving developers without a reliable tool. This prompted Linus Torvalds, the creator of Linux, to develop Git.</p><p>Git was built with key objectives:</p><ul><li><strong>Speed and efficiency</strong></li><li><strong>A simple yet flexible design</strong></li><li><strong>Robust branching support for parallel development</strong></li><li><strong>A distributed system where every user has a full repository copy</strong></li><li><strong>Scalability for handling large projects like the Linux kernel</strong></li></ul><p>Since its release in 2005, Git has become one of the most widely used version control systems, valued for its speed, reliability, and powerful branching capabilities.</p><p><strong>💠 Git Basics</strong></p><p>This section introduces fundamental Git commands that you’ll use regularly for managing your projects efficiently.</p><ul><li><strong>The Three States</strong></li></ul><p>The key to understanding Git is recognizing its three main file states, Git tracks files through three main states: Modified, Staged, Committed</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/697/1*qruumwlEPjbRygpIfrvwNQ.png" /><figcaption>git three-tier architecture</figcaption></figure><p>The typical Git workflow follows these steps:</p><ol><li>Modify files in your working directory.</li><li>Stage specific changes that you want to include in the next commit, adding them to the staging area.</li><li>Commit the staged changes, creating a permanent snapshot in your Git repository.</li></ol><p><strong>🔸Installing Git</strong></p><p>Before using Git, you need to ensure it’s installed on your computer. Even if it’s already present, updating to the latest version is recommended. You can install Git using a package manager or another installer of your choice.</p><pre>// Installing on macOS<br>$ brew install git</pre><pre>// Installing on Windows<br>https://git-scm.com/download/win</pre><p><strong>🔸First-Time Git Setup</strong></p><p>After installing Git, it’s a good idea to configure your environment. These settings are typically done once per computer and persist across updates. The most important initial setup is setting your user name and email address, as Git associates this information with every commit you make.</p><pre>$ git config --global user.name &quot;Cpt Mactavish&quot;<br>$ git config --global user.email mactavish@example.com</pre><p><strong>🔸Getting a Git Repository</strong></p><p>You can get a Git repository in one of two ways:</p><ul><li>You can convert an existing local directory into a Git repository by initializing version control with Git.</li></ul><pre># for macOS<br>$ cd /Users/cptmactavish/sample_git_project<br># for Windows<br>$ cd C:/Users/cptmactavish/sample_git_project</pre><pre># type<br>$ git init<br># By default, when you initialize a new Git repository using git init, Git creates a branch called &#39;main&#39;.<br># This creates a new subdirectory named .git that contains all of your necessary repository files</pre><ul><li>If you have an existing project and want to start tracking its files with Git, you need to add them to version control and make an initial commit. You can do this by running,</li></ul><pre>$ git add *.ts<br>$ git add LICENSE<br>$ git commit -m &#39;Initial project version&#39;</pre><p>This stages the files you want to track and commits them to your repository, marking the starting point of version control for your project.</p><pre># Go to your GitHub (or GitLab/Bitbucket) repo and copy the HTTPS or SSH URL.<br># It&#39;ll look like this, <br>https://github.com/username/reponame.git<br># Then run,<br>git remote add origin https://github.com/username/reponame.git<br># Now verify,<br>git remote -v<br># You should see,<br>origin  https://github.com/username/reponame.git (fetch)<br>origin  https://github.com/username/reponame.git (push)<br># Push your branch, since you&#39;re on master, run,<br>git push -u origin master #-u flag sets upstream tracking</pre><ul><li>You can create a local copy of an existing Git repository by cloning it. This allows you to work on the project independently while staying connected to the original repository.</li></ul><pre>$ git clone https://github.com/sampleuser/sample_git_project</pre><p>🔸<strong>Recording Changes to the Repository</strong></p><p>After setting up your Git repository, the next step is to track changes and commit them.</p><p>▪ Check which files have changed</p><pre>$ git status<br>$ git status -s</pre><p>▪ Add a file to the staging area</p><pre># The git add command serves multiple purposes. It is primarily used to track new files, stage changes before committing, and mark merge-conflicted files as resolved. <br># This command moves changes from the working directory to the staging area, preparing them for the next commit.<br>$ git add README.md<br></pre><p>▪ Commit the staged changes with a message</p><pre># Capitalized, short (50 chars or less) summary<br>$ git commit -m “Add a new file”</pre><p>▪ Add all modified files at once</p><pre>$ git add .</pre><p>▪ lists all the files that are currently being tracked by Git in your repository.</p><pre># Files that are in the index (staged) and under Git tracking<br>git ls-files<br># Does not include: Untracked files (not yet added with git add), Ignored files (in .gitignore)</pre><p>▪ Viewing the Commit History</p><pre># You can see a record of all commits made in your repository.<br>$ git log<br>$ git log --oneline</pre><p>▪ Ignoring Files</p><p>To prevent Git from tracking certain files, such as logs or build artifacts, you can create a .gitignore file that defines patterns for files to ignore. Here’s an example:</p><pre># The command cat in this context is a Unix/Linux command that stands for &quot;concatenate&quot;. It is used to display the contents of a file in the terminal.<br>$ cat .gitignore</pre><pre># Ignore node modules and build files<br># Ignores the node_modules folder (common in Node.js projects)<br>node_modules/<br># Ignores the dist folder (typically contains build output)<br>dist/<br># Ignore log files<br>*.log<br># Ignore Screenshots<br>screenshots/<br># Ignores all files ending in .o or .a (main.o / lib.a)<br>*.[oa]<br># Ignore ResponseData<br>/src/projectName/responseData</pre><p>▪ Undoing Things</p><p>If you commit too soon and need to include additional changes or fix the commit message, you can use,</p><pre># This allows you to modify the previous commit by adding new changes or editing the commit message without creating a new commit.<br>$ git commit --amend</pre><pre>#  Deletes file from disk and Git tracking<br>git rm file.txt</pre><pre># Removes the file(s)/directory from Git&#39;s tracking without deleting them from your computer.<br>git rm -r --cached<br>git rm -r --cached node_modules</pre><p>▪ Unstaging a Staged File</p><p>If you accidentally stage multiple files using git add * but want to unstage one while keeping the changes, you can use the following command:</p><pre># to unstage a file<br>git reset HEAD &lt;file&gt;<br></pre><p><strong>🔸Working with Remotes</strong></p><p>To collaborate on a Git project, you must manage remote repositories — versions of your project hosted online or on a network. You can have multiple remote repositories, each with read-only or read/write access. Effective collaboration requires pushing and pulling data between these repositories to share updates and stay in sync with others.</p><p>The “upstream branch” is the remote branch that your local branch is linked to (i.e., tracks). It is usually used to:</p><ul><li>Pull changes (git pull) from that branch</li><li>Push changes (git push) to that branch</li></ul><pre># This -u (or --set-upstream) sets the upstream branch so that next time you can just use<br>git push -u origin feature/login<br>git push --set-upstream origin master<br># Mainly need when you create a new branch locally &amp; trying to push it without specify the remote branch</pre><p>▪ Fetching, Pulling &amp; Pushing with Remotes</p><pre># The command fetches all new data from the remote repository that is not yet present in your local repository.<br>$ git fetch &lt;remote&gt;<br><br># You can use the git pull command to fetch the latest changes from a remote branch and merge them into your current branch automatically. <br># This can simplify your workflow and keep your local repository up to date.<br>$ git pull &lt;remote&gt;<br><br># When your project is ready to be shared, you need to push it to a remote repository.<br>$ git push origin master</pre><p><strong>Conclusion</strong></p><p>By now, you are equipped with the essential Git skills needed to work locally. You can create or clone repositories, make and track changes, stage and commit updates, and reviewing the repository’s history.</p><p>Happy Learning!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0a1a79a7d522" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Beginner’s Guide to Learning Rest Assured — Java for API Automation.]]></title>
            <link>https://medium.com/@malitthh/a-beginners-guide-to-learning-rest-assured-java-for-api-automation-193871b8b183?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/193871b8b183</guid>
            <category><![CDATA[test-engineering]]></category>
            <category><![CDATA[api-testing]]></category>
            <category><![CDATA[restassured]]></category>
            <category><![CDATA[information-technology]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Wed, 03 Jul 2024 16:58:21 GMT</pubDate>
            <atom:updated>2025-03-23T16:53:35.671Z</atom:updated>
            <content:encoded><![CDATA[<h3>A Beginner’s Guide to Learning Rest Assured — Java for API Automation.</h3><h4>Basics of API Testing &amp; Rest Assured.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NSyqXXWgwU7vbDwZCQp2NA.jpeg" /></figure><p>API automation is an essential skill in the realm of software testing, and Rest Assured is one of the most popular tools for this purpose, especially for Java developers. This guide aims to provide a structured approach to learning Rest Assured, making your journey smoother and more efficient.</p><p><strong>Step 1: Understand the Basics of API and REST</strong></p><p>Before diving into Rest Assured, it’s crucial to have a solid understanding of what APIs (Application Programming Interfaces) and REST (Representational State Transfer) are. Here’s a brief overview:</p><ul><li><strong>API:</strong> An interface that allows different software applications to communicate with each other.</li><li><strong>REST:</strong> A set of principles for designing networked applications. It relies on stateless, client-server communication, typically over HTTP.</li></ul><p><strong>Step 2: Set Up Your Development Environment</strong></p><p>To work with Rest Assured, you need to set up your development environment. Here’s how you can do it:</p><ol><li><strong>Install Java Development Kit (JDK):</strong> Ensure you have JDK installed on your system. You can download it from the <a href="https://www.oracle.com/java/technologies/javase-downloads.html">Oracle website</a>.</li><li><strong>Install an Integrated Development Environment (IDE):</strong> Popular choices include IntelliJ IDEA, Eclipse.</li><li><strong>Set Up Maven:</strong> Rest Assured is available as a Maven dependency, so you’ll need to have Maven installed. You can download Maven from the <a href="https://maven.apache.org/download.cgi">Apache Maven website</a>. (When you create a Maven project in Eclipse or IntelliJ IDEA you typically don’t need to manually install Maven because those IDEs comes with its own embedded version of Maven)</li><li><strong>Create a Maven Project:</strong> In your IDE, create a new Maven project. This will allow you to manage dependencies easily.</li></ol><p><strong>Step 3: Add Rest Assured Dependency</strong></p><p>Add Rest Assured to your Maven project by including the following dependency in your pom.xml file:</p><pre>&lt;!-- REST Assured dependency --&gt;<br>  &lt;dependency&gt;<br>   &lt;groupId&gt;io.rest-assured&lt;/groupId&gt;<br>   &lt;artifactId&gt;rest-assured&lt;/artifactId&gt;<br>   &lt;version&gt;4.4.0&lt;/version&gt;<br>   &lt;scope&gt;test&lt;/scope&gt;<br>  &lt;/dependency&gt;</pre><p>Make sure to check for the latest version on the Maven Repository.</p><p><a href="https://mvnrepository.com/">https://mvnrepository.com/</a></p><p><strong>Step 4: Learn the Basics of Rest Assured</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/472/1*Ipv7bMFbl3SzchEZaue72w.png" /><figcaption>Simple Project Structure</figcaption></figure><p>Rest Assured provides a simple and intuitive syntax for making HTTP requests and validating responses. Here’s a basic example of how to make a GET request:</p><pre>@Test(priority=1)<br>void addaNewPet() {<br>     given()<br>         .contentType(&quot;application/json&quot;)<br>         .body(&quot;{ \&quot;id\&quot;: 7, \&quot;category\&quot;: { \&quot;id\&quot;: 5, \&quot;name\&quot;: \&quot;Bravo\&quot; }, \&quot;name\&quot;: \&quot;Bravo\&quot;, \&quot;photoUrls\&quot;: [ \&quot;abcdefg.lk\&quot; ], \&quot;tags\&quot;: [ { \&quot;id\&quot;: 7, \&quot;name\&quot;: \&quot;Bravo\&quot; } ], \&quot;status\&quot;: \&quot;pending\&quot; }&quot;)<br>     .when()<br>         .post(&quot;https://petstore.swagger.io/v2/pet&quot;)<br>     .then()<br>         .statusCode(200);<br> }</pre><p>Just to make sure it’s created, you can go to the Petstore Swagger mentioned below, and find the GET method to find the pet by ID. Pass the ID value you gave here, and the created pet will be there.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7W1YDz4lU5G8cau4GLWq3A.png" /><figcaption>Swagger UI</figcaption></figure><p>Using the BDD (Behavior-Driven Development) format provided by Rest Assured is a common and recommended way to write tests for RESTful APIs because it makes the tests readable and easier to understand.</p><p><strong>Explanation of given(), when() &amp; then()</strong></p><ul><li><strong>given()</strong>: Sets up the request. Here, you specify headers, parameters, request body, etc.</li><li><strong>when()</strong>: Describes the action that triggers the request, such as get, post, put, delete, etc.</li><li><strong>then()</strong>: Validates the response. Here, you assert the status code, response body, headers, etc.</li></ul><p>While the BDD format is recommended for its readability and alignment with BDD practices, Rest Assured also supports a non-BDD format:</p><pre>@Test(priority=1)<br> void addANewPet() {<br>     RequestSpecification request = RestAssured.given();<br>     request.contentType(&quot;application/json&quot;);<br>     request.body(&quot;{ \&quot;id\&quot;: 7, \&quot;category\&quot;: { \&quot;id\&quot;: 5, \&quot;name\&quot;: \&quot;Bravo\&quot; }, \&quot;name\&quot;: \&quot;Bravo\&quot;, \&quot;photoUrls\&quot;: [ \&quot;abcdefg.lk\&quot; ], \&quot;tags\&quot;: [ { \&quot;id\&quot;: 7, \&quot;name\&quot;: \&quot;Bravo\&quot; } ], \&quot;status\&quot;: \&quot;pending\&quot; }&quot;);<br><br>     Response response = request.post(&quot;https://petstore.swagger.io/v2/pet&quot;);<br>     Assert.assertEquals(response.getStatusCode(), 200);<br> }</pre><p><strong>Step 5: Running The Script</strong></p><p>You can run the script using the TestNG plugin. Make sure the TestNG plugin is installed in Eclipse. Simply add the TestNG dependency to your project. You can install TestNG via the Eclipse Marketplace. Then, click on the test class and select, Run As -&gt; TestNG Test.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/729/1*6zq6kydhoAN5yPl8yf0WCA.png" /><figcaption>Running the script</figcaption></figure><p><strong>Step 6: Explore Advanced Features</strong></p><p>Once you’re comfortable with the basics, explore the advanced features of Rest Assured:</p><ul><li><strong>Path Parameters:</strong> Learn how to handle dynamic paths in your requests.</li><li><strong>Query Parameters:</strong> Understand how to add query parameters to your requests.</li><li><strong>Headers:</strong> Discover how to add headers to your requests.</li><li><strong>Authentication:</strong> Explore how to handle different types of authentication.</li><li><strong>Assertions:</strong> Learn how to make assertions on the response data.</li></ul><p><strong>Step 7: Practice with Real APIs</strong></p><p>To gain practical experience, practice by automating real APIs. Some good options include:</p><p>e.g., <a href="https://reqres.in/">Reqres</a>, <a href="https://petstore.swagger.io/">https://petstore.swagger.io/</a></p><p>These APIs provide a variety of endpoints that you can use to practice different types of requests and validations.</p><p>e.g., <a href="https://www.postman.com/templates/collections/tags/quality-engineers/">https://www.postman.com/templates/collections/tags/quality-engineers/</a></p><p><strong>Conclusion</strong></p><p>Learning Rest Assured for API automation is a valuable skill that can significantly enhance your testing capabilities. By following this structured approach, you’ll be able to master Rest Assured and apply it effectively in your projects. Remember, practice is key to becoming proficient, so keep experimenting with different APIs and scenarios.</p><p>Happy learning!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=193871b8b183" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Choosing the Right Test Automation Framework for Your Project.]]></title>
            <link>https://medium.com/@malitthh/choosing-the-right-test-automation-framework-for-your-project-f9e57a4e1f37?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9e57a4e1f37</guid>
            <category><![CDATA[planning]]></category>
            <category><![CDATA[framework]]></category>
            <category><![CDATA[software-testing]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Tue, 25 Jun 2024 08:07:22 GMT</pubDate>
            <atom:updated>2025-02-05T04:30:01.982Z</atom:updated>
            <content:encoded><![CDATA[<h4>Framework Selection and Initial Setup for Success.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*koRvJGNhpSik6CqEdJPC5g.jpeg" /></figure><p>In the fast-paced world of software development, ensuring the quality and reliability of applications is crucial. Test automation frameworks are essential to this process because they offer an organized and effective method of performing tests. Still, it can be difficult to choose the best framework for your project given the wide range of options. This blog aims to guide you through the key considerations and steps to help you make an informed decision.</p><p><strong>Understanding Test Automation Frameworks</strong></p><p>A test automation framework is a structured approach &amp; a set of guidelines or rules used for automate software testing or repetitive tasks. Enhancing efficiency and accuracy. The functionality and complexity of frameworks vary, ranging from simple record-and-playback tools to broad data-driven and behavior-driven development (BDD) frameworks.</p><p>To get started, let’s begin with a scenario,</p><blockquote>“MediClaim Portal,” designed to enhance the efficiency of medical claims processing. A policyholder logs into the portal and uploads their surgery invoice, doctor’s prescription, and medical reports. The ML-AI-powered system swiftly processes these documents, extracting crucial information such as surgery details, incurred costs, and doctor’s notes, and generates a concise summary. This summary is presented in a clear format for the medical staff to review. The staff receives a notification of the policyholder’s submission and accesses the dedicated dashboard to review the summarized information alongside the original documents. Satisfied with the completeness and accuracy of the information, the staff approves the policyholder’s claim. The policyholder is then notified of the approval and the expected reimbursement date via both email and a push notification on the mobile app.</blockquote><p>By following these steps, you can decide which tools or frameworks to use for the project,</p><p><strong>Step 1: Make A List Of Features &amp; Project Requirements</strong></p><p>Understanding the specific needs of your project is the first step. Consider factors like,</p><ul><li><strong>Cross-browser Testing</strong> — The web application must be compatible with all major browsers including Internet Explorer, Safari, Chrome, Opera, Firefox, and Microsoft Edge.</li><li><strong>Mobile Automation on Both iOS and Android Devices</strong> — The application has native mobile versions for both Android and iOS.</li><li><strong>Tab and Iframe Support</strong> — The web application includes iframes on each page and links that open in new tabs.</li></ul><p>“An inline frame (iframe) is a HTML element that loads another HTML page within the document. It essentially puts another webpage within the parent page.”</p><ul><li><strong>API Automation </strong>— Automate tests to validate data collection and communication through APIs across different interfaces.</li><li><strong>Performance Testing</strong>—<strong> </strong>Ensure that the performance of the project is thoroughly tested to measure response times and scalability under various user loads and usage scenarios. This includes assessing the system’s ability to handle concurrent document processing and maintaining optimal performance levels across different operational conditions.</li><li><strong>Data-driven Testing </strong>— Implement tests using various data inputs (e.g., different medical claim scenarios) to validate application behavior.</li><li><strong>Database Automation </strong>— Develop automated tests to validate data stored in the database related to medical claims and user interactions.</li></ul><p><strong>Step 2: Team Expertise</strong></p><p>By carefully assessing your team’s skills and aligning them with the specific requirements of the project, you can make informed decisions on selecting automation tools and frameworks. Prioritize capabilities such as iframe handling alongside broader considerations of programming language proficiency, testing experience, and long-term strategic alignment.</p><p><strong>Step 3: Ease of Use</strong></p><p>The framework should be easy to set up and use. A steep learning curve can delay the testing process and affect productivity. Look for frameworks with good documentation and community support.</p><p><strong>Step 4: Scalability and Flexibility</strong></p><p>Choose a framework that can scale with your project. It should be flexible enough to integrate with various tools and adapt to changing requirements. This is crucial for long-term projects where needs may evolve.</p><p><strong>Step 5: Integration with CI/CD Pipelines</strong></p><p>In modern development environments, continuous integration and continuous deployment (CI/CD) are standard practices. Ensure that the framework you choose seamlessly integrates with CI/CD tools.</p><p><strong>Step 6: Cost</strong></p><p>While some frameworks are open-source and free, others may require a license. Consider your budget and evaluate whether the features of a paid framework justify its cost.</p><p><strong>Step 7: Shortlist Tools and Frameworks</strong></p><p>Once you’ve researched and compared existing tools, narrow down your options to create a shortlist of tools and frameworks that best meet your project’s requirements. Consider the following criteria,</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/758/1*teJGf_BeQ9EeRd3QxVJNGg.png" /><figcaption>E.g.,Tool Selection Table</figcaption></figure><blockquote>Note: Correction to be made for the table “The comparison table lists the tools in the columns and the requirements in the rows. The cells contain information about each tool’s properties concerning each requirement, along with priority details, as specified in the ‘ISTQB CTAL-TAE Syllabus v2.0’.”</blockquote><p><strong>Step 8: Conduct Proof of Concept (PoC)</strong></p><p>Before committing fully, conduct a Proof of Concept (PoC) with the shortlisted tools to validate their suitability for the project.</p><p><strong>Conclusion</strong></p><p>Selecting a suitable test automation framework is an important decision that can greatly influence the efficacy and efficiency of your testing process. You can choose the framework that best suits your needs by carefully considering the features of several frameworks, your team’s experience, and the requirements of your project. Keep in mind that the objective is to maximize the testing effort while improving the software’s quality and dependability.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9e57a4e1f37" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mastering Performance Testing with K6 and JavaScript.]]></title>
            <link>https://blog.stackademic.com/mastering-performance-testing-with-k6-and-javascript-6349ed235458?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/6349ed235458</guid>
            <category><![CDATA[performance-testing]]></category>
            <category><![CDATA[software-testing]]></category>
            <category><![CDATA[k6]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[quality-assurance]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Sun, 15 Oct 2023 05:06:15 GMT</pubDate>
            <atom:updated>2026-01-02T14:09:02.291Z</atom:updated>
            <content:encoded><![CDATA[<h4>Basics of Performance Testing &amp; K6.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tgPv6s8rwMhA7tr9saJ_pQ.jpeg" /></figure><p><strong>Performance Testing</strong></p><p>In today’s digital age, web applications and services are expected to deliver high performance and reliability to meet user expectations. To ensure your applications can handle real-world traffic and load, performance testing is crucial, What is Performance Testing, is a term for measuring how a system or application performs overall, this could include testing for evaluate the speed, scalability, reliability, responsiveness &amp; resource usage of an application under expected &amp; peak load condition.</p><blockquote><strong>Types of Load Testing</strong></blockquote><p>There are several types, here are a few examples</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_I7qjqYVfy67QW8jQrWgYg.png" /><figcaption>Load Testing Types — From GrafanaLabs</figcaption></figure><ol><li>Load Testing — Load testing involves testing the stability and response time of a system by applying a load that is typically less than or average to the design number of users. e.g. AverageLoad, Smoke</li><li>Stress Testing — In stress testing, you increase the load or resource usage to above average level that system’s capacity.</li><li>Spike Testing — Spike testing increases to extremely high loads in a very short or non-existent ramp-up time. In the same way, the ramp-down is very fast or non-existent, letting the process iterate only once.</li><li>Soak Testing — Soak testing, also known as endurance testing, is a type of performance testing that focuses on assessing how a system performs over an extended period under a consistent, sustained load.</li></ol><blockquote><strong>Performance Testing does use some Mathematical and Statistical Concepts.</strong></blockquote><p>Let’s break it down in a practical way.</p><ol><li>Averages, Median, Percentiles &amp; Response Times</li></ol><ul><li><strong>Mean (μ) (Avg) </strong>— when you see “Avg response time” in tools, it usually means arithmetic mean.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*v_NzOkgCJAM9Wh8VNzx3Ew.png" /><figcaption>Formula 1</figcaption></figure><ul><li>Problem<strong>: </strong>A few very slow requests can hide inside a good-looking average.</li><li>e.g., 100, 110, 120, 130, 5000 → Average = 1,092ms, But 4 out of 5 users were fast.</li><li><strong>Median (50th Percentile) </strong>— the middle value when data is sorted. Useful because avg can be skewed by outliers.</li></ul><blockquote>Most real systems fail not because of average, but because of slow outliers.</blockquote><p>e.g., [100, 200, 2000] → mean = 766ms, but median = 200ms</p><ul><li><strong>Percentiles (p90, p95, p99th)</strong> — shows what % of requests completed within a certain time. often more valuable than mean.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/234/1*HG-PK-q4JRHY-1Tdiah1CA.png" /><figcaption>Formula 2</figcaption></figure><p>e.g., [100,200,300,400,500] — Sort the data (ascending)</p><ul><li>p = percentile (95 in our case)</li><li>n = number of data points (5 here)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/355/1*5hANCUYByQ7LGMeCNXVJAQ.png" /><figcaption>Formula 2.1</figcaption></figure><ul><li>Rank = 5.7 → the 95th percentile is between the <strong>5th</strong> and <strong>6th</strong> value.</li><li>But we only have 5 values → so we interpolate between the 5th value (500) and the “next” value (which doesn’t exist, so we take it as the max = 500).</li><li>p95–95% of responses were equal to or faster than this value, ≤ 500ms.</li></ul><blockquote>This exposes tail latency, which users actually feel. Most requests are fast. A small percentage are <em>much</em> slower, and that slow end stretches out like a long tail on a graph.</blockquote><blockquote>Cloud systems naturally produce long-tail latency due to shared resources, queueing effects, and dependency fan-out, which is why percentiles matter more than averages.</blockquote><blockquote>Why cloud systems naturally produce long tails,</blockquote><ol><li>Shared infrastructure</li><li>Queueing theory (Little’s Law in action)</li><li>Garbage collection &amp; memory management</li><li>Network unpredictability</li><li>Dependency fan-out</li><li>Cold starts &amp; autoscaling</li></ol><ul><li>The slowest (5%) took longer than 500ms.</li></ul><blockquote>you can say it like this, “The system’s p95 latency is 500ms, meaning 95% of requests complete within this time, with only the slowest 5% exceeding it”</blockquote><blockquote>Average shows overall performance, but percentiles show user experience. A good average can hide slow requests, while p95 ensures most users aren’t affected by latency spikes.</blockquote><p>2. Variability &amp; Spread</p><ul><li><strong>Standard deviation (σ)</strong> — measures how spread out response times are from the mean, indicate the system stability.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/242/1*ZU3jluXP8xKXnXyb7af4MQ.png" /><figcaption>Formula 3</figcaption></figure><p>e.g., <strong>Low σ</strong> → most response times are clustered near the mean → system is predictable. <strong>High σ</strong> → response times are spread out → some users are much slower than others.</p><ul><li>a low σ → stable system, a high σ → inconsistent response time</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*78KOGuGchFB0lGLsEZWjCA.png" /><figcaption>Formula 3: Explanation</figcaption></figure><p>But how do we decide “low” vs “high”? There’s no single universal threshold, but here are ways industry people judge it:</p><ul><li><strong>Compare σ to the Mean (Coefficient of Variation)</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/148/1*L0_uMLVLrQe7D9yA8x-uJQ.png" /><figcaption>Formula 3.1</figcaption></figure><ul><li>CV &lt; 0.1 (10%) → <strong>very stable</strong> system.</li><li>CV 0.1–0.3 (10–30%) → <strong>acceptable variance</strong>.</li><li>CV &gt; 0.3 (30%+) → <strong>unstable/unpredictable</strong>.</li></ul><p>e.g., Mean = 200ms, σ = 20ms → CV = 0.1 → stable, Mean = 200ms, σ = 120ms → CV = 0.6 → unstable.</p><ul><li>Compare Across Test Runs / Baselines</li></ul><p>e.g., Run load test today → σ = 30ms, Run same test after deployment → σ = 200ms.</p><ul><li><strong>Variance — square of standard deviation</strong></li></ul><p>3. Growth &amp; Load Patterns</p><ul><li>Linear — increase at a constant rate</li><li>Exponential — extreme scaling</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KyvA2E1d2YhtQD8RL_masQ.png" /><figcaption>Graph showing <strong>linear growth (y = x)</strong> compared to <strong>exponential growth (y = e^(0.5x))</strong>.</figcaption></figure><p>4. Queuing &amp; Capacity Concepts</p><ul><li><strong>Littles Law in Performance Testing</strong> — Little’s Law helps in estimating the number of concurrent users or requests in a system based on the arrival rate and average response time.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/164/1*nYSA1ELv_WPnhX8FFRMf0Q.png" /><figcaption>Formula 4</figcaption></figure><ul><li>L = avg concurrent requests in system</li><li>λ = arrival rate (req/sec)</li><li>W = avg response time</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/569/1*nMtaW4t47FZxI4ohC4Ha9w.png" /><figcaption>Formula 4: Explanation</figcaption></figure><p>Meaning: on average, 5 requests are “inside” the system at any moment.</p><p>e.g., You send 100 req/sec, but system can only process 60 req/sec.</p><ul><li>λ (arrival rate) = 100 req/sec (you’re still sending them).</li><li>Throughput (completion rate) = 60 req/sec.</li><li>Queue builds up → L increases.</li><li>This is why <strong>arrival rate ≠ throughput</strong> under stress.</li></ul><blockquote><strong>KPIs (key performance indicators) for Performance Testing</strong></blockquote><ol><li>Throughput — which tells you how many requests were sent per second on average during the test execution.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/361/1*e8gUKNPkFMC9ThoEZvARvg.png" /><figcaption>Formula 5</figcaption></figure><p>2. Response Time — (e.g., for Acceptor API, for e2e flow to complete)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/185/1*EZ_vn-KX3IHJFt9TDtwYnQ.png" /><figcaption>Formula 6</figcaption></figure><p>x₁ = each response time, n = number of requests</p><p>3. Latency &amp; Percentile Values — Latency is generally considered to be the amount of time it takes from when a request is made by the user to the time it takes for the response to get back to that user.</p><p>4. Error Rate — Percentage of failed requests. (means some requests completely failed, e.g., timeouts, server error.)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/351/1*BI57kno4FGo-tqgEp2qLjg.png" /><figcaption>Formula 7</figcaption></figure><p>5. Resources Utilizations</p><p>When initiating Performance Testing, it’s crucial to follow these steps:</p><ol><li>Define the performance objectives.</li><li>Design and identify the key scenarios.</li><li>Design the test environment.</li><li>Develop the test script.</li><li>Execute the tests.</li><li>Analyze the results.</li><li>Optimize and retest.</li></ol><p>Now, let’s shift our focus to k6.</p><blockquote><strong>K6</strong></blockquote><p>K6 is a developer-centric, open-source performance testing tool designed to be simple, efficient, and scriptable. It allows you to write test scripts in JavaScript, making it accessible to developers with various backgrounds and expertise levels.</p><p><strong>Why Choose K6 for Performance Testing?</strong></p><ol><li>Ease of Use</li><li>Open Source</li><li>Scripting Flexibility</li><li>High Performance</li></ol><p><strong>Getting Started with K6 and JavaScript</strong></p><p>Let’s take a closer look at how to create performance tests using K6 and JavaScript.</p><p><strong>Installation</strong> — Start by installing K6 using your package manager (e.g., npm or Homebrew). Once installed, you can verify its version and check the available options using the command-line interface.</p><pre>for Windows (Winget is a package manager for Windows that allows you to easily install and manage various software packages),<br>    &quot;winget install k6&quot; or &quot;winget install --id k6.k6&quot;<br>for Mac,<br>    &quot;brew install k6&quot;<br>for version check,<br>    &quot;k6 --version&quot;</pre><p>1. Initialize a new Node.js project, This creates a package.json file to manage dependencies.</p><pre>mkdir k6-performance  # Create a folder named &#39;k6-performance&#39;<br>cd k6-performance     # Navigate into the folder<br>npm init -y           # Initialize a Node.js project with default settings (creates package.json)</pre><p>2. Install required dependencies.</p><pre>npm install typescript ts-loader webpack webpack-cli eslint prettier dotenv json-loader --save-dev</pre><p>3. Configure TypeScript (tsconfig.json) — tsconfig.json file is a configuration file for TypeScript projects. It defines compiler options and settings to control how TypeScript compiles .ts files into JavaScript.</p><p>4. Set Up Webpack (webpack.config.js) — file is a configuration file for Webpack, a powerful module bundler used in JavaScript applications. It defines how Webpack processes, transforms, and bundles files like JavaScript, TypeScript, CSS, and images.</p><p>5. Create a folder structure to organize your scripts, common actions, testdata, and other resources. A common structure could be,</p><pre>k6-performance/<br>├── dist/                             # Compiled files<br>├── node_modules/                     # Dependencies<br>├── src/                              # Source code<br>│   ├── perf_tests/                   # Test scripts<br>│   │   ├── Petstore/<br>│   │   │   ├── GET_APIs/<br>│   │   │   │   ├── petstoreService.ts<br>│   │   │   ├── POST_APIs/<br>│   │   │   │   ├── getCorrelationId.ts<br>│   ├── testdata/                     # Test data<br>├── .eslintignore                     # ESLint ignore rules<br>├── .eslintrc.js                      # ESLint config<br>├── common.env                        # Environment variables<br>├── package.json                      # Node.js config<br>├── package-lock.json<br>├── Performance_Test_Report.md        # Documentation<br>├── README.md                         # Project Readme<br>├── run_k6.sh                         # Shell script to execute tests<br>├── tsconfig.json                     # TypeScript config<br>├── webpack.config.js                 # Webpack config<br>└── k6.exe                            # K6 CLI tool</pre><p>6. Add ESLint &amp; Prettier</p><p>7. Write Your First Test Script — Create a new TypeScript file for your test script. K6 provides a simple and intuitive API to define your test scenarios. You can set up HTTP requests, specify user flows, and define thresholds for performance metrics such as response time and error rates.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z2VeaWv4dtiQUjGRvlFPMw.png" /><figcaption>K6 Framework folder structure</figcaption></figure><p>This is a basic outline for creating a beginner-level K6 framework.</p><p>Sample POST script below,</p><pre>import http from &quot;k6/http&quot;;<br>import { check } from &quot;k6&quot;;<br><br>export const options = {<br>    thresholds: {<br>        http_req_duration: [&quot;p(95)&lt;7000&quot;],<br>        http_req_duration: [&quot;p(75)&lt;9500&quot;], <br>        checks: [&quot;rate&gt;0.95&quot;],<br>        http_req_failed: [&quot;rate&lt;0.1&quot;],<br>    },<br>    noConnectionReuse: true,<br>    scenarios: {<br>        constant_scenario: {<br>            executor: &#39;constant-arrival-rate&#39;,<br>            duration: &#39;30s&#39;,<br>            rate: 10,<br>            timeUnit: &#39;1s&#39;,<br>            preAllocatedVUs: 50,<br>            maxVUs: 100,<br>        }<br>    }<br>};<br><br>export default function () {<br>    let data = {<br>        Data: &quot;K6 is a developer-centric, open-source performance testing tool designed to be simple, efficient, and scriptable. It allows you to write test scripts in JavaScript, making it accessible to developers with various backgrounds and expertise levels.&quot;,<br>        Department: &quot;Grafana&quot;,<br>        Software: &quot;K6&quot;,<br>        Date: &quot;23/02/2025&quot;,<br>        Url: &quot;https://sample.swagger.io/english/list&quot;<br>    };<br><br>    const params = {<br>        headers: {<br>            &quot;Content-Type&quot;: &quot;application/json&quot;,<br>            Accept: &quot;*/*&quot;,<br>            Token: &quot;sample_token&quot;,<br>        },<br>    };<br><br>    const url = &quot;https://petstore.swagger.io/v2/pet&quot;;<br>    const res = http.post(url, JSON.stringify(data), params);<br>    const req = JSON.parse(res.body);<br>    console.log(req.request_id, res.status);<br><br>    check(res, {<br>        &quot;is status 202&quot;: (rs) =&gt; rs.status === 202,<br>    });<br><br>}</pre><p><strong>Test Scenarios &amp; Executors</strong> — To simulate user behavior, define one or more test scenarios within your script. Each scenario should include HTTP requests to various endpoints of your application. You can control the number of virtual users, ramp-up periods, and test duration.</p><ol><li>Shared Iterations — A fixed total number of iterations is <em>shared</em> among a set number of virtual users (VUs).<br> Iterations are distributed between VUs, but not evenly, some VUs may do more work than others. The test ends when all iterations are complete.</li><li>Per VU Iterations — Each VU executes an <em>exact and fixed number of iterations</em>. Total iterations = VUs × iterations per VU. This is useful when you want exactly the same load (in terms of iterations) from each VU.</li><li>Constant VUs — A fixed number of VUs runs for a <em>specified duration</em>, executing as many iterations as possible within that time.<br> This models constant concurrent users running the test workload.</li><li>Ramping VUs — A <em>changing (ramped) number of VUs</em> over time runs as many iterations as possible. You define a series of stages to increase/decrease target VUs. This lets you simulate load changing over the test period.</li><li>Constant Arrival Rate — A fixed <em>iteration start rate</em> (e.g., iterations per second) is maintained for a specified period. It <em>dynamically adjusts the number of VUs</em> as needed to try to keep that rate steady, regardless of iteration execution time.</li><li>Ramping Arrival Rate — A <em>changing iteration start rate</em> over time. i.e., the rate of iteration starts increases or decreases based on stages. k6 will adjust the number of VUs dynamically to meet that target rate schedule.</li></ol><pre>Overall average RPM = (start + end) / 2 x Duration<br>  <br>  {target:4, duration:&quot;1m&quot;} - e.g., Avg RPM = (4 x 1) = 4 Requests<br>  {target:6, duration:&quot;2m&quot;} - e.g., Avg RPM = (4 + 6) / 2 = 5 RPM x 2 = 10 Requests<br>  {target:10, duration:&quot;3m&quot;} - e.g., Avg RPM = (6 + 10) / 2 = 8 RPM x 3 = 24 Requests <br>  {target:20, duration:&quot;4m&quot;} - e.g., Avg RPM = (10 + 20) / 2 = 15 RPM x 4 = 60 Requests<br> <br>e.g., Avg RPM = 98 Requests<br>e.g., Avg RPM = (4 + 20) / 2 = 12 RPM x 10 = 120 Requests (upper bound)</pre><p><strong>Assertions</strong> — K6 allows you to set assertions (Checks) to validate the Boolean condition in your tests. Testers often use checks to validate that the system is responding with the expected content.</p><pre>check(res, {<br>            //&#39;HTTP Status is 200 or 201&#39;: (rs) =&gt; rs.status === 200 || 201,<br>            &#39;HTTP Status is 200 or 201&#39;: (rs) =&gt; rs.status === 200 || rs.status === 201,<br>            &#39;Response Body &quot;Status&quot;&#39;: (rs) =&gt; {<br>                const responseBody = rs?.json();<br>                const checkStatus = responseBody?.Status === &#39;DONE&#39;;<br>                console.log(`Response Body Check Result for Request ID ${reqid}: ${checkStatus}`);<br>                return checkStatus; <br>            }<br>        });<br>// The ?. operator in JavaScript and TypeScript is called the optional chaining operator. <br>// It allows you to safely access deeply nested properties of an object without having to check if each level exists, preventing runtime errors.</pre><p><strong>Execution</strong> — Run your K6 test script using the command line. K6 will simulate user behavior, gather performance data, and generate insightful reports. You can customize the output format and specify thresholds for performance metrics.</p><pre>- How to run Locally - K6 run path of the test,<br>K6 run &#39;copy path&#39;</pre><p><strong>Reporting &amp; Visualizations</strong></p><p>To complement the performance test results executed using k6, we have included additional supporting artifacts to enhance analysis and visibility. A detailed summary table outlining key performance metrics is provided in the attached Word document. Furthermore, a custom Python script has been developed to generate a percentile distribution graph from the database-exported results, allowing for deeper insight into response time behavior across various thresholds.</p><pre>https://github.com/Malitthh/medium-content-hub/blob/master/docs/Sample%20Performance%20Test%20Report.docx<br>https://github.com/Malitthh/medium-content-hub/blob/master/code/job_duration_analyzer.py</pre><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FgvounvDSDGg%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DgvounvDSDGg&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FgvounvDSDGg%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7b8fa5752b9ce4eb3fa4012b3fe7f4cc/href">https://medium.com/media/7b8fa5752b9ce4eb3fa4012b3fe7f4cc/href</a></iframe><p>Reference</p><ul><li><a href="https://aws.amazon.com/compare/the-difference-between-throughput-and-latency/">Throughput vs Latency - Difference Between Computer Network Performances - AWS</a></li><li><a href="https://grafana.com/load-testing/types-of-load-testing/">Types of load testing | Grafana Labs</a></li></ul><p><strong>Conclusion</strong></p><p>Performance testing is essential for ensuring the reliability and scalability of your web applications. K6, with its JavaScript scripting capabilities, provides a user-friendly and powerful solution for performance testing. Its open-source nature, ease of use, and scripting flexibility make it a top choice for developers and testers alike.</p><p>By leveraging K6 and JavaScript, you can simulate user behavior, analyze performance metrics, and identify areas for improvement in your application. This combination enables you to deliver a robust and high-performance user experience, ultimately leading to greater user satisfaction and the success of your digital projects.</p><p>Happy learning!</p><h3>A message from our Founder</h3><p><strong>Hey, </strong><a href="https://linkedin.com/in/sunilsandhu"><strong>Sunil</strong></a><strong> here.</strong> I wanted to take a moment to thank you for reading until the end and for being a part of this community.</p><p>Did you know that our team run these publications as a volunteer effort to over 3.5m monthly readers? <strong>We don’t receive any funding, we do this to support the community. ❤️</strong></p><p>If you want to show some love, please take a moment to <strong>follow me on </strong><a href="https://linkedin.com/in/sunilsandhu"><strong>LinkedIn</strong></a><strong>, </strong><a href="https://tiktok.com/@messyfounder"><strong>TikTok</strong></a>, <a href="https://instagram.com/sunilsandhu"><strong>Instagram</strong></a>. You can also subscribe to our <a href="https://newsletter.plainenglish.io/"><strong>weekly newsletter</strong></a>.</p><p>And before you go, don’t forget to <strong>clap</strong> and <strong>follow</strong> the writer️!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6349ed235458" width="1" height="1" alt=""><hr><p><a href="https://blog.stackademic.com/mastering-performance-testing-with-k6-and-javascript-6349ed235458">Mastering Performance Testing with K6 and JavaScript.</a> was originally published in <a href="https://blog.stackademic.com">Stackademic</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Playwright 101: Beginner’s Guide.]]></title>
            <link>https://medium.com/@malitthh/playwright-101-beginners-guide-5352efe589a5?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/5352efe589a5</guid>
            <category><![CDATA[microsoft]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[playwright-automation]]></category>
            <category><![CDATA[software-testing]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Thu, 27 Jul 2023 12:19:26 GMT</pubDate>
            <atom:updated>2025-03-11T14:47:11.358Z</atom:updated>
            <content:encoded><![CDATA[<h4>Setting Up, Writing Tests and Creating a Framework.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9yqyLbODWVKHQB1744QCkw.jpeg" /></figure><p><strong>Playwright Introduction</strong></p><p>Playwright is an open-source testing library developed using TypeScript by Microsoft. As a robust and versatile tool, Playwright allows developers and testers to conduct end-to-end testing of web applications efficiently. Leveraging the capabilities of TypeScript, Playwright offers a seamless and user-friendly experience for creating robust test suites.</p><p><strong>Comparison of Playwright and Cypress</strong></p><p>Both Playwright and Cypress are well-known testing tools, yet they have differences. Here are some variations:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/643/1*vZ_jL3HQUn-1fJotAo3TyA.png" /><figcaption>Playwright-Cypress Comparison Table</figcaption></figure><p><strong>Advantages of Playwright</strong></p><ol><li>Cross-Browser Support: Playwright supports multiple browsers, including Chrome, Firefox, WebKit (Safari), and Microsoft Edge. This allows you to run tests on different browsers easily, ensuring your web application works consistently across various environments.</li><li>Automating Complex Scenarios: Playwright can handle more complex web application scenarios, such as file downloads, handling browser dialogs, and interacting with web components like iframes and shadow DOM elements.</li><li>Speed and Performance: Playwright is designed for speed and improved performance. It can execute tests faster, making the testing process more efficient.</li><li>Parallel Testing: Playwright has built-in support for parallel testing, allowing you to run tests concurrently across multiple browser instances, which can significantly reduce test execution time.</li><li>Headless and Headful Mode: Playwright supports both headless (no GUI) and headful (with GUI) modes, giving you the flexibility to choose the appropriate mode based on your testing needs.</li><li>Mobile Device Emulation: Playwright allows you to emulate mobile devices and test your web application’s responsiveness and behavior on different screen sizes.</li><li>Support for Multiple Programming Languages: Playwright offers bindings for various programming languages, including JavaScript, TypeScript, Python, and C#, making it accessible to developers from different tech stacks.</li><li>Robust Wait and Synchronization Mechanisms: Playwright provides advanced wait and synchronization mechanisms, ensuring that your tests interact with the web application at the right moments, improving test reliability.</li><li>Community and Support: Playwright has an active community and is actively maintained by Microsoft, which means you can find resources, documentation, and community support to help you get started and resolve any issues you encounter.</li></ol><p><strong>Setting up the Playwright Environment</strong></p><p>Setting up a Playwright environment is easy. Here are the steps:</p><p>1.Install Node.js and set “NODE_HOME” environmental variable.<br>2.Create a new Playwright working directory.<br>3.Navigate to the working directory in the terminal.<br>4.Run “npm init playwright@latest” to initialize the project.</p><p><strong>Here’s an example of a Playwright Script:</strong></p><pre>import { test, expect } from &quot;@playwright/test&quot;;<br>import commons from &quot;../../pages/commons.page&quot;;<br><br>test.describe(&quot;Playwright 101: Beginner&#39;s Guide&quot;, async () =&gt; {<br>  //Qmetry - SwagLabs-TC-001<br>  test(&quot;Add to Cart&quot;, async ({ page }) =&gt; {<br>    const common = new commons(page);<br>    const randomData = commons.generateRandomData();<br><br>    await common.login(&#39;standard_user&#39;, &#39;secret_sauce&#39;);<br>    await common.addtoCart();<br>    await common.checkoutProcess(randomData);<br>  });<br>});</pre><p><strong>Few Playwright Commands:</strong></p><ul><li><strong>Running the Tests</strong></li></ul><ol><li>npx playwright test --ui - UI mode</li><li>npx playwright test - run all tests</li><li>npx playwright test AddtoCart.spec.ts - run a specific test</li><li>npx playwright test AddtoCart.spec.ts --project chromium --headed - run a specific test with UI with specific browser</li><li>npx playwright codegen --test-id-attribute=&quot;data-cy&quot; - playwright recorder</li></ol><ul><li><strong>Report Generation</strong></li></ul><ol><li>npx playwright show-report - to view the report</li></ol><p><strong>Page Object Model in Playwright</strong></p><p>The Page Object Model (POM) is a design pattern for organizing test code in a way that makes it easier to maintain and reuse. In Playwright, the POM can be implemented using custom commands and page objects. Here’s an example of how to implement the POM in Playwright:</p><ol><li>Create a new folder called “pages” in the root of your project.</li><li>Create a new file in the “pages” folder called “commons.page.ts”.</li><li>In “commons.page.ts”, create a new class called “commons”.</li><li>Add methods to the “commons” class for locating and interacting with the elements.</li><li>Under “e2e” folder create a script “AddtoCart.spec.ts”</li><li>In “AddtoCart.spec.ts” here u can create an object of commons page and access methods to the script.</li></ol><p>Here’s an example of how the “commons.ts” file might look:</p><pre>const { test, expect } = require(&quot;@playwright/test&quot;);<br>import { Locator, Page } from &quot;@playwright/test&quot;;<br><br>export class commons {<br>  readonly page: Page;<br>  readonly usernameInputField:Locator;<br>  readonly passowrdInputField:Locator;<br>  readonly loginButton:Locator;<br>  readonly pageTitle:Locator;<br><br>  constructor(page: Page) {<br>    this.page = page;<br>    this.usernameInputField = page.getByPlaceholder(&quot;Username&quot;);<br>    this.passowrdInputField = page.getByPlaceholder(&quot;Password&quot;);<br>    this.loginButton = page.locator(&#39;[data-test=&quot;login-button&quot;]&#39;);<br>    this.pageTitle = page.getByText(&#39;Swag Labs&#39;);<br>  }<br><br>  /**<br>   * @description Navigate to base URL<br>   * @example common.navigateToBaseUrl()<br>   */<br>  async navigateToBaseUrl() {<br>    await this.page.goto(&#39;/&#39;);<br>  }<br><br>  /**<br>   * @description Login to the application<br>   * @param username: any<br>   * @param password: any<br>   * @example common.login(userName, Password)<br>   */<br>  async login(username: any, password: any ) {<br>    await this.page.goto(&#39;/&#39;);<br>    await this.usernameInputField.click();<br>    await this.usernameInputField.fill(username);<br>    await this.passowrdInputField.click();<br>    await this.passowrdInputField.fill(password);<br>    await this.loginButton.click();<br>    expect (this.pageTitle).toBeVisible();<br>  }<br><br>  async addtoCart() {<br>    await this.addToCartBackpackButton.click();<br>    await this.addToCartTShirtButton.click();<br>    await this.addToCartJacketButton.click();<br>    await this.shoppingCartLink.click();<br>  }<br><br>  static generateRandomData() {<br>    const randomFirstName = `Soap${Math.floor(Math.random() * 100)}`;<br>    const randomLastName = `Mactavish${Math.floor(Math.random() * 100)}`;<br>    const randomZip = Math.floor(Math.random() * 10000);<br>    return {<br>      namefirst: randomFirstName,<br>      namelast: randomLastName,<br>      zip: randomZip.toString(),<br>    };<br>  }<br>}<br>export default commons;</pre><p>And here’s an example of how the “AddtoCart.spec.ts” file might look:</p><pre>import { test, expect } from &quot;@playwright/test&quot;;<br>import commons from &quot;../../pages/commons.page&quot;;<br><br>test.describe(&quot;Playwright 101: Beginner&#39;s Guide&quot;, async () =&gt; {<br>  //Qmetry - SwagLabs-TC-001<br>  test(&quot;Add to Cart&quot;, async ({ page }) =&gt; {<br>    const common = new commons(page);<br>    const randomData = commons.generateRandomData();<br><br>    await common.login(&#39;standard_user&#39;, &#39;secret_sauce&#39;);<br>    await common.addtoCart();<br>    await common.checkoutProcess(randomData);<br>  });<br>});<br><br></pre><p><strong>Creating a Framework</strong></p><p>Creating a Playwright framework involves organizing your test code, defining reusable functions, and structuring the project to facilitate easy maintenance and scalability.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8XIRsgllesfnUlwhi4d7sA.png" /><figcaption>e.g: Sample Framework</figcaption></figure><p>Create a folder structure to organize your tests, page objects, utilities, and other resources. A common structure could be,</p><pre>├── e2e (to store your test scripts)<br>│   ├── AddtoCart.spec.ts<br>│   ├── dashboard.spec.ts<br>│   └── ...<br>├── pages (to store your web elements and methods relevent to your scripts)<br>│   ├── commons.page.ts<br>│   ├── Dashboard.Page.ts<br>│   └── ...<br>├── supports (to store Utill files, and commands files)<br>│   ├── commands.ts<br>│   └── ...<br>├── fixtures (to store test data files)<br>│   ├── testData.json<br>│   ├── Excel.xls<br>│   └── ...<br>└── playwright.config.ts<br>└── tsconfig.json<br>└── package-lock.json<br>└── package.json</pre><p>This is a basic outline for creating a beginner-level Playwright framework. Depending on your project’s requirements, you can add more advanced features like test reporting, data-driven testing, parallel execution, etc.</p><p><a href="https://playwright.dev/docs/intro">https://playwright.dev/docs/intro</a> — Playwright Documentation</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FWgp1a1XRq3I%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DWgp1a1XRq3I&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FWgp1a1XRq3I%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/04e46a0f01d684cf636eab1f7b8d5ff6/href">https://medium.com/media/04e46a0f01d684cf636eab1f7b8d5ff6/href</a></iframe><p><strong>Conclusion</strong></p><p>In Summary, Playwright is a powerful end-to-end testing framework developed by Microsoft. It offers developers a simple and effective approach to creating and executing tests. With its distinctive features like automated waiting, real-time reloads, and powerful debugging tools, Playwright has become a popular choice among engineers for web application testing.</p><p>You’ve reached the end of the article. Here’s a sample project to begin your journey with Playwright. Try cloning this repository to your machine, learn, and contribute to the open-source community.</p><p><a href="https://github.com/Malitthh/playwright-automation.git">https://github.com/Malitthh/playwright-automation.git</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5352efe589a5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agile Testing and Quality Assurance.]]></title>
            <link>https://medium.com/@malitthh/agile-testing-and-quality-assurance-af0da05a2107?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/af0da05a2107</guid>
            <category><![CDATA[agile-testing]]></category>
            <category><![CDATA[agile-methodology]]></category>
            <category><![CDATA[software-dev-life-cycle]]></category>
            <category><![CDATA[software-testing]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Wed, 19 Jul 2023 01:44:01 GMT</pubDate>
            <atom:updated>2023-07-28T12:55:22.847Z</atom:updated>
            <content:encoded><![CDATA[<h4>Strategies for Successful Software Delivery.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x-apa3rqKZtCKt3TrGmi_w.jpeg" /></figure><p>In the world of software development, agile testing has become an essential part of the process. Agile testing is a methodology that emphasizes collaboration, flexibility, and speed in the testing phase of software development. It focuses on continuous feedback, early defect detection, and continuous improvement. In this article, we will discuss what agile testing is, the principles behind it, the different methodologies, the agile testing lifecycle, the role of a tester in an agile team.</p><p>We will also cover best practices for implementing agile testing in your organization, common challenges faced by teams when adopting agile testing, and the impact of agile testing on software quality and customer satisfaction.</p><p><strong>What is Agile Testing?</strong></p><ul><li>Agile testing is a technique for software testing that aligns with the agile methodology.</li><li>It gives importance to testing throughout the software development process, rather than just at the end. The approach involves continuous testing and feedback, fostering collaboration between development and testing teams and prioritizing the delivery of top notch software.</li></ul><p><strong>Agile Testing Principles</strong></p><p>There are four core principles of agile testing:</p><ul><li>Testing is an integral part of the software development process.</li><li>Test early and often.</li><li>Embrace change and adapt to it.</li><li>Collaborate and communicate with the development team.</li></ul><p><strong>Agile Testing Methodologies</strong></p><p>There are several agile testing methodologies that teams can use. Some of the popular ones include:</p><ul><li>Scrum: A framework that emphasizes iterative and incremental development. Testing is done in sprints, with each sprint delivering a potentially shippable product increment.</li><li>Extreme Programming (XP): A methodology that emphasizes continuous integration, automated testing, and customer involvement.</li><li>Kanban: A method that emphasizes visualizing workflow, limiting work in progress, and delivering small batches of work.</li></ul><p><strong>Agile Testing Lifecycle</strong></p><p>The agile testing lifecycle is an iterative process that involves the following phases:</p><ul><li>Test Planning: This involves defining the scope of testing, identifying the testing objectives, and creating a test plan.</li><li>Test Design: This involves creating test cases based on the requirements and design of the software.</li><li>Test Execution: This involves running the tests and reporting any defects.</li><li>Test Reporting: This involves reporting the results of the testing, including any defects found and their severity.</li><li>Test Retesting: This involves retesting any defects that were found and fixed during the previous phases of testing to ensure that they have been completely resolved and that there are no new defects introduced as a result of the fixes.</li><li>Test Closure: This involves completing the testing process and analyzing the results to identify areas for improvement.</li></ul><p><strong>Role of a Tester in an Agile Team</strong></p><p>In an agile team,</p><ul><li>The role of the tester is to ensure that the software being developed meets the quality standards set by the team.</li><li>The Tester works closely with the developers and other team members to identify potential defects and provide feedback on the software’s functionality.</li><li>The Tester is responsible for creating test plans, executing tests, and reporting any defects found.</li><li>They are also involved in the continuous improvement process by providing feedback on the testing process and suggesting areas for improvement.</li></ul><p><strong>Best Practices for Implementing Agile Testing in Your Organization</strong></p><p>Implementing agile testing in your organization can be challenging. Here are some best practices to help you successfully adopt agile testing:</p><ul><li>Train your team: Make sure that your team is trained on agile testing principles and methodologies. Provide them with the necessary tools and resources to implement agile testing.</li><li>Collaborate with your team: Encourage collaboration between your development and testing teams. This will help to ensure that everyone is working towards the same goals and that testing is integrated throughout the software development lifecycle.</li><li>Prioritize testing: Make sure that testing is a priority and that it is integrated throughout the software development lifecycle. This will help to ensure that defects are caught early and that the software is delivered on time and with high quality.</li><li>Automate testing: Use automation tools to automate as much testing as possible. This will help to ensure that testing is done consistently and efficiently.</li><li>Focus on continuous improvement: Encourage your team to continuously improve the testing process. This will help to ensure that the team is always learning and improving, and that the testing process is as effective as possible.</li></ul><p><strong>Common Challenges Faced by Teams When Adopting Agile Testing</strong></p><p>Adopting agile testing can be challenging. Here are some common challenges that teams face:</p><ul><li>Resistance to change: Some team members may be resistant to changing the way they work. This can make it difficult to adopt agile testing.</li><li>Lack of resources: Teams may not have the necessary resources to implement agile testing effectively. This can include tools, training, and personnel.</li><li>Lack of collaboration: Teams may struggle to collaborate effectively, which can make it difficult to integrate testing throughout the software development lifecycle.</li><li>Lack of expertise: Teams may not have the necessary expertise in agile testing to implement it effectively.</li><li>Lack of leadership support: Without support from leadership, it can be difficult to implement agile testing effectively.</li></ul><p><strong>The Impact of Agile Testing on Software Quality and Customer Satisfaction</strong></p><ul><li>Agile testing can greatly influence the quality of software and satisfaction of customers. By detecting defects in the early stages of development, agile testing ensures timely delivery of high quality software. This, in turn, enhances customer satisfaction and fosters loyalty.</li><li>Moreover, integrating testing into every phase of software development enables agile testing to pinpoint areas of enhancement and facilitates continuous learning and improvement for the team.</li></ul><p><strong>Conclusion</strong></p><p>Testing in an agile environment plays a vital role in software development. It puts great importance on teamwork, adaptability and efficiency during the testing stage of software creation. Through the adoption of proven agile testing methods, teams can effectively incorporate agile testing into their workflow and tackle common obstacles. By placing emphasis on ongoing enhancement and integrating testing throughout the entire software development process, teams can enhance software quality and ultimately satisfy customers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af0da05a2107" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Streamline Your Selenium Java Automation Projects with Azure Pipelines.]]></title>
            <link>https://medium.com/@malitthh/streamline-your-selenium-java-automation-projects-with-azure-pipelines-ccae856b1de5?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/ccae856b1de5</guid>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[selenium]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[azure-devops]]></category>
            <category><![CDATA[integration]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Wed, 19 Apr 2023 05:50:39 GMT</pubDate>
            <atom:updated>2025-09-16T03:14:23.076Z</atom:updated>
            <content:encoded><![CDATA[<h4>How to Integrate Java Selenium Automation Projects with Azure Pipelines.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4-Wjep96UNEqyyDoMKvd6g.jpeg" /></figure><p>Automation testing has become a crucial component of the software development life cycle as software development processes continue to advance. Software testers and developers may build reliable automated tests with Selenium Java that can run on several platforms and browsers.</p><p>Azure Pipelines, on the other hand, is a powerful continuous integration and continuous deployment (CI/CD) platform that enables developers to build, test, and deploy applications. By integrating Selenium Java automation project with Azure Pipelines, software development teams can automate the testing process and deliver quality software quickly.</p><p>This article will walk you through the integration of a Selenium Java automation project with Azure Pipelines, outlining how to use YAML files, how to build using Maven, and the benefits of this approach.</p><p>Step 1: Create a Java project with Selenium WebDriver The first step is to create a Java project with Selenium WebDriver, which will contain the test cases to be executed. This project can be created using an Integrated Development Environment (IDE) such as Eclipse or IntelliJ IDEA. Once the project has been made, include all necessary Selenium WebDriver dependencies in the POM.xml file.</p><p>Here is an example POM.xml file,</p><pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;<br>         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;<br>         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;<br>    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;<br><br>    &lt;groupId&gt;com.Test.automationframwork&lt;/groupId&gt;<br>    &lt;artifactId&gt;TestWeb&lt;/artifactId&gt;<br>    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;<br><br>    &lt;dependencies&gt;<br><br>        &lt;!-- https://mvnrepository.com/artifact/org.testng/testng --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.testng&lt;/groupId&gt;<br>            &lt;artifactId&gt;testng&lt;/artifactId&gt;<br>            &lt;version&gt;7.0.0&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/rg.seleniumhq.selenium/selenium-java --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>            &lt;artifactId&gt;selenium-java&lt;/artifactId&gt;<br>            &lt;version&gt;3.141.59&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/org.uncommons/reportng --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.uncommons&lt;/groupId&gt;<br>            &lt;artifactId&gt;reportng&lt;/artifactId&gt;<br>            &lt;version&gt;1.1.4&lt;/version&gt;<br>            &lt;scope&gt;test&lt;/scope&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-firefox-driver --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>            &lt;artifactId&gt;selenium-firefox-driver&lt;/artifactId&gt;<br>            &lt;version&gt;3.141.59&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-chrome-driver --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>            &lt;artifactId&gt;selenium-chrome-driver&lt;/artifactId&gt;<br>            &lt;version&gt;3.141.59&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-edge-driver --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.seleniumhq.selenium&lt;/groupId&gt;<br>            &lt;artifactId&gt;selenium-edge-driver&lt;/artifactId&gt;<br>            &lt;version&gt;3.141.59&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;io.github.bonigarcia&lt;/groupId&gt;<br>            &lt;artifactId&gt;webdrivermanager&lt;/artifactId&gt;<br>            &lt;version&gt;3.7.1&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br>            &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;<br>            &lt;version&gt;3.8.1&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/commons-io/commons-io --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;commons-io&lt;/groupId&gt;<br>            &lt;artifactId&gt;commons-io&lt;/artifactId&gt;<br>            &lt;version&gt;2.6&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/com.aventstack/extentreports --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;com.aventstack&lt;/groupId&gt;<br>            &lt;artifactId&gt;extentreports&lt;/artifactId&gt;<br>            &lt;version&gt;4.1.7&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;com.relevantcodes&lt;/groupId&gt;<br>            &lt;artifactId&gt;extentreports&lt;/artifactId&gt;<br>            &lt;version&gt;2.41.2&lt;/version&gt;<br>        &lt;/dependency&gt;<br>        &lt;!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-surefire-plugin --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br>            &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;<br>            &lt;version&gt;3.0.0-M5&lt;/version&gt;<br>        &lt;/dependency&gt;<br><br>    &lt;/dependencies&gt;<br><br>    &lt;profiles&gt;<br>        &lt;!-- regression --&gt;<br>        &lt;profile&gt;<br>            &lt;id&gt; regression &lt;/id&gt;<br>            &lt;build&gt;<br>                &lt;pluginManagement&gt;<br>                    &lt;plugins&gt;<br>                        &lt;plugin&gt;<br>                            &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;<br>                            &lt;version&gt; 2.18.1&lt;/version&gt;<br>                            &lt;configuration&gt;<br>                                &lt;suiteXmlFiles&gt;<br>                                    &lt;suiteXmlFile&gt;<br>                                        RegressionSuite.xml<br>                                    &lt;/suiteXmlFile&gt;<br>                                &lt;/suiteXmlFiles&gt;<br>                            &lt;/configuration&gt;<br>                        &lt;/plugin&gt;<br>                    &lt;/plugins&gt;<br>                &lt;/pluginManagement&gt;<br>            &lt;/build&gt;<br>        &lt;/profile&gt;<br>    &lt;/profiles&gt;<br><br>    &lt;build&gt;<br>        &lt;sourceDirectory&gt;src&lt;/sourceDirectory&gt;<br>        &lt;plugins&gt;<br>            &lt;plugin&gt;<br>                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br>                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;<br>                &lt;configuration&gt;<br>                    &lt;source&gt;1.8&lt;/source&gt;<br>                    &lt;target&gt;1.8&lt;/target&gt;<br>                &lt;/configuration&gt;<br>            &lt;/plugin&gt;<br>        &lt;/plugins&gt;<br>    &lt;/build&gt;<br><br>&lt;/project&gt;</pre><p>Step 2: Create a repository in Azure DevOps The next step is to create a repository in Azure DevOps to store the Java project. To do this, go to Azure DevOps, create a new project, and after that, create a new repository inside the project.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kLoMi4myP_uHUUakpdsLrQ.png" /><figcaption>Azure DevOps Repository</figcaption></figure><ul><li>Step 3: Configure the Build Pipeline using YAML. To configure the build pipeline using YAML, you need to create a YAML file in your repository. The YAML file defines the build configuration.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*REko0igvdSWHM33DF-mHYw.png" /><figcaption>Create a new pipeline</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lIgfh5NLxtDB93zv2jKomA.png" /><figcaption>Connect your Repository from here</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gW8Vm52LV4g1XuKOpxRiOQ.png" /><figcaption>Select your Repository</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1r7WztAXELv7trgcgU2edQ.png" /><figcaption>Configure your pipeline and click Save and run</figcaption></figure><p>Here is an example YAML file,</p><pre># Starter pipeline<br># Start with a minimal pipeline that you can customize to build and deploy your code.<br># Add steps that build, run tests, deploy, and more:<br># https://aka.ms/yaml<br><br>trigger: none<br><br>stages:<br>  - stage: test<br>    pool:<br>      vmImage: windows-latest<br>    jobs:<br>      - job: myjob<br>        steps:<br><br>        - task: Maven@3<br>          inputs:<br>            mavenPomFile: ‘pom.xml’<br>            mavenOption: ‘-Xmx3072m’<br>            javaHomeOption: ‘JDKVersion’<br>            jdkArchitectureOption: ‘x64&#39;<br>            publishJUnitResults: true<br>            testResultsFiles: ‘**/surefire-reports/TEST-*.xml’<br>            testRunTitle: ‘dev_Test_Results’<br>            options: ‘-P regression&#39;<br>            #goals: &#39;package&#39;<br>            mavenAuthenticateFeed: false<br>            effectivePomSkip: false<br>            sonarQubeRunAnalysis: false</pre><p>This code is a YAML file that defines a basic Azure Pipeline for building and testing.</p><ul><li>The pipeline has one stage, test, which consists of one job, myjob.</li><li>The trigger section indicates that this pipeline is not triggered by any events. This is useful for pipelines that are intended to be manually triggered.</li><li>The stages section defines the stages of the pipeline. Here, there is only one stage, test.</li><li>The pool section specifies the virtual machine image that should be used for the stage. As you can see, the windows-latest image is used.</li><li>The jobs section defines the jobs that should be run in the stage. In here, there is only one job, myjob.</li><li>The steps section lists the tasks that should be run in the job. In this YAML, the only step is a Maven task, Maven@3.</li><li>The Java application must be built and tested via the Maven task. It requires a number of input parameters, all of which are listed in the inputssection.</li><li>The mavenPomFile input specifies the location of the pom.xml file, which is the Maven project file.</li></ul><p>Step 4: Add a test task After configuring the build pipeline, add a task to run the test cases in the pipeline.</p><p>Step 5: Publish the test results online. Use the test reporting functionality in Azure Pipelines to publish the test results once the test cases have been run. This enables you to evaluate the test findings and, if necessary, take corrective action. Add a new job to the pipeline and use the test reporting option to do this. The test result format and file path should then be specified.</p><p>Step 6: Trigger the pipeline Once you have configured the pipeline, you can trigger it manually or automatically whenever changes are made to the repository. This can be done by selecting the appropriate trigger option in the pipeline settings.</p><p><strong>The advantages of integrating an automation suite with Azure, including:</strong></p><ol><li>Faster and more dependable software delivery: By automating the build, testing, and deployment processes, you can reduce the time it takes to deliver product while also making sure that it is thoroughly and consistently tested.</li><li>Better collaboration and communication: The automation suite for Azure offers a single platform for development, testing, and deployment, which makes it easier for developers, testers, and other stakeholders to collaborate and communicate.</li><li>Better software: You can run tests fast and simply using Azure’s automation suite, ensuring that your software is of high quality and satisfies your customers’ needs.</li><li>Greater scalability and flexibility: Automation suite for Azure gives you the opportunity to expand your testing and deployment processes fast and efficiently.</li><li>Better reporting and visibility: Azure’s automation package offers real-time insight into the state of your software delivery pipeline, allowing you to see issues as they occur and take appropriate action</li></ol><p><strong>Conclusion</strong></p><p>There are several advantages for Testers and companies in integrating a Selenium Java automation project with Azure Pipelines and utilizing YAML files for the work. Teams can guarantee accurate and reliable results. Additionally, teams can speed up their development and deployment workflows and reduce the time it takes for the applications to reach the market by utilizing the strength of Azure Pipelines and its connection with other tools and services. Continuous testing enables businesses to have confidence in the quality of their software and provide value to consumers with each release.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ccae856b1de5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Getting Started with Cypress.]]></title>
            <link>https://medium.com/@malitthh/getting-started-with-cypress-6ab917e7a5cd?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/6ab917e7a5cd</guid>
            <category><![CDATA[cypress]]></category>
            <category><![CDATA[test-automation]]></category>
            <category><![CDATA[quality-engineering]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Fri, 24 Mar 2023 11:57:41 GMT</pubDate>
            <atom:updated>2025-03-11T14:50:33.619Z</atom:updated>
            <content:encoded><![CDATA[<h4>How to Set Up, Use Page Object Models and Locators.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KSgivDbvv_TRJYdQsmbljg.jpeg" /></figure><p><strong>Cypress Introduction</strong></p><p>The open-source testing tool Cypress enables Testers to create comprehensive tests for web applications. A quick, dependable, and user-friendly testing environment for web applications is offered by this JavaScript-based framework. In comparison to other well-known testing tools like Selenium, Cypress is a relatively new tool, but because to its numerous benefits, it has already become quite popular among Testers.</p><p><strong>Comparison of Cypress and Selenium</strong></p><p>Both Cypress and Selenium are well-known testing tools, yet they have numerous differences. Here are some significant variations:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/637/1*kFAw1C4q_inBw8k7UWPnJA.png" /><figcaption>Cypress-Selenium Comparison Table</figcaption></figure><p><strong>Advantages of Cypress</strong></p><p>Cypress has many advantages over other testing tools. Here are some of the key advantages:</p><ul><li><strong>Easy to install and set up</strong><br>Cypress is easy to install and set up. It comes with a built-in test runner and does not require any additional dependencies or setup.</li><li><strong>Fast and reliable</strong><br>Cypress is fast and reliable. It runs tests directly in the browser, which makes it faster and more reliable than other testing tools.</li><li><strong>Easy to debug</strong><br>Cypress is easy to debug. It provides a built-in test runner that allows developers to easily debug their tests.</li><li><strong>Easy to use</strong><br>Cypress is easy to use. It has a simple and intuitive API that allows developers to write tests quickly and easily.</li><li><strong>Automatic waiting</strong><br>Cypress automatically waits for commands and assertions to complete before moving on to the next command, which makes tests more reliable.</li></ul><p><strong>Disadvantages of Cypress</strong></p><p>While Cypress has many advantages, there are also some disadvantages to using it. Here are some of the key disadvantages:</p><ul><li>Limited Browser Support</li></ul><p>Cypress has expanded its browser support over time, but it still primarily supports Chromium-based browsers (Chrome, Edge, Electron) and Firefox. While Safari support is not natively available, it is possible to run tests in WebKit using experimental features. However, cross-browser testing is still more limited compared to Selenium and Playwright.</p><ul><li>Limited Testing Capabilities</li></ul><p>Cypress is primarily designed for end-to-end (E2E) testing but has expanded to support component testing as well. However, it still lacks native support for API testing, visual regression testing, and extensive mobile browser automation. While workarounds exist, tools like Playwright may offer more flexibility in these areas.</p><p><strong>Setting up the Cypress Environment</strong></p><p>Setting up a Cypress environment is easy. Here are the steps:</p><p>1.Install Node.js and set “NODE_HOME” environmental variable. <br>2.Create a new Cypress working directory.<br>3.Navigate to the working directory in the terminal.<br>4.Run “npm init -y” to initialize the project.<br>5.Install Cypress by running “npm install cypress — save-dev”.</p><p><strong>Here’s an example of a simple Cypress Script:</strong></p><pre>describe(&#39;Test Suite&#39;, function(){<br>    it(&#39;Verify title of the page&#39;,()=&gt;{<br>        cy.visit(&#39;https://demo.nopcommerce.com&#39;);<br>        cy.title().should(&#39;eq&#39;,&#39;nopCommerce demo store&#39;);<br>    })<br>})</pre><p>6. Open Cypress by running “npx cypress open”.</p><p><strong>Using Locators in Cypress</strong></p><p>Cypress provides several ways to locate elements on a web page, including CSS selectors, XPath selectors, and custom attributes. Here’s an example of how to locate an element using a CSS selector:</p><pre>cy.get(&#39;#my-element&#39;).click()</pre><p>This code uses the cy.get() command to locate an element with the ID “my-element” and then clicks on it. Cypress also provides several other commands for interacting with UI elements, including type(), select(), and check() etc.</p><p><strong>Interacting with UI Elements</strong></p><p>In addition to locating elements, Cypress provides several commands for interacting with UI elements. Here’s an example of how to fill out a form in Cypress:</p><pre>cy.get(&#39;#name&#39;).type(&#39;Soap Mactavish&#39;)<br>cy.get(&#39;#email&#39;).type(&#39;soap24@abc.com&#39;)<br>cy.get(&#39;#submit-button&#39;).click()</pre><p>This code uses the type() command to fill out the “name” and “email” fields, and then clicks on the “submit” button.</p><blockquote>Use data-test attributes instead of generic id/class selectors to avoid flakiness.</blockquote><p><strong>Page Object Model in Cypress</strong></p><p>The <strong>Page Object Model (POM)</strong> is a design pattern that helps organize test code, making it more maintainable and reusable. In Cypress, the POM can be implemented using<strong> </strong>JavaScript/TypeScript classes<strong> </strong>and custom commands.</p><p>Steps to Implement POM in Cypress,</p><ol><li>Create a “pages” folder in the root of your project.</li><li>Create a new file in the “pages” folder, e.g., LoginPage.js.</li><li>Define a class in LoginPage.js that encapsulates the locators and methods for interacting with the login page.</li><li>Use Cypress commands<strong> (</strong>cy.get<strong>)</strong> inside the class methods for interacting with page elements.</li><li>Use the page object in test files to keep test logic clean.</li><li>(Optional) Create custom Cypress commands to simplify login logic.<br>Here’s an example of how the “LoginPage.js” file might look:</li></ol><pre>class LoginPage {<br>  visit() {<br>    cy.visit(&#39;/login&#39;)<br>  }<br><br>  fillUsername(username) {<br>    cy.get(&#39;[data-test=username]&#39;).type(username)  // Use data-test attributes for better stability<br>  }<br><br>  fillPassword(password) {<br>    cy.get(&#39;[data-test=password]&#39;).type(password)<br>  }<br><br>  submit() {<br>    cy.get(&#39;[data-test=submit-button]&#39;).click()<br>  }<br><br>  login(username, password) {<br>    this.visit()<br>    this.fillUsername(username)<br>    this.fillPassword(password)<br>    this.submit()<br>  }<br>}<br><br>export default new LoginPage()</pre><p>And here’s an example: Using LoginPage.js in a Test</p><pre>import LoginPage from &#39;../pages/LoginPage&#39;<br><br>describe(&#39;Login Test&#39;, () =&gt; {<br>  it(&#39;should log in successfully&#39;, () =&gt; {<br>    LoginPage.login(&#39;testuser&#39;, &#39;password123&#39;)<br>    cy.url().should(&#39;include&#39;, &#39;/dashboard&#39;)  // Assertion to verify login success<br>  })<br>})</pre><p>(Optional) Using Cypress Custom Commands</p><p>Instead of calling LoginPage.login(), you can define a Cypress custom command in commands.js:</p><pre>import LoginPage from &#39;../pages/LoginPage&#39;<br><br>Cypress.Commands.add(&#39;login&#39;, (username, password) =&gt; {<br>  LoginPage.login(username, password)<br>})</pre><p>Now you can use cy.login() in your tests:</p><pre>describe(&#39;Login Test&#39;, () =&gt; {<br>  it(&#39;should log in successfully&#39;, () =&gt; {<br>    cy.login(&#39;testuser&#39;, &#39;password123&#39;)<br>    cy.url().should(&#39;include&#39;, &#39;/dashboard&#39;)<br>  })<br>})</pre><p><a href="https://docs.cypress.io/guides/overview/why-cypress">https://docs.cypress.io/guides/overview/why-cypress</a> — Cypress Documentation</p><p><strong>Conclusion</strong></p><p>In summary, Cypress is an effective end-to-end testing framework that gives engineers a simple and effective approach to create and execute tests. Cypress has quickly become a favorite among engineers thanks to its distinctive features including automated waiting, real-time reloads, and powerful debugging tools.</p><p>Happy learning!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6ab917e7a5cd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Integration Testing.]]></title>
            <link>https://medium.com/@malitthh/integration-testing-a-comprehensive-guide-to-improving-your-applications-quality-944f877a836e?source=rss-1158dabec505------2</link>
            <guid isPermaLink="false">https://medium.com/p/944f877a836e</guid>
            <category><![CDATA[basics]]></category>
            <category><![CDATA[integration-testing]]></category>
            <category><![CDATA[software-testing]]></category>
            <category><![CDATA[quality-engineering]]></category>
            <dc:creator><![CDATA[Malith Senadheera]]></dc:creator>
            <pubDate>Wed, 01 Mar 2023 14:02:39 GMT</pubDate>
            <atom:updated>2025-02-23T12:41:45.762Z</atom:updated>
            <content:encoded><![CDATA[<h4>A Comprehensive Guide to Improving Your Application’s Quality.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q3eve2Uw3Z-i44AoWd1ZaQ.jpeg" /></figure><p>A software testing approach called integration testing combines separate system components or units and evaluates them all at once. Integration testing is used to find dependencies and conflicts between components and make sure the merged system satisfies both functional and non-functional requirements.</p><p><strong>Integration Testing Introduction</strong></p><p>Integration testing is a step in the software testing process that follows unit testing. It verifies that the interactions between the individual components or modules of a system work as intended when combined. Integration testing helps to identify any gaps or flaws in the integration of the system components and to ensure that the system behaves as expected.</p><p><strong>How Integration Testing Works</strong></p><p>Integration testing starts after the successful completion of unit testing. In integration testing, the individual units or components of a system are combined and tested as a group. The integration process involves testing the interactions between the components, including data exchange and control flow. The main objective is to ensure that the components work together seamlessly and that the system meets the specified requirements.</p><p><strong>What Integration Testing Does</strong></p><p>Integration testing verifies the functional and non-functional requirements of a system. It helps to identify any issues with the integration of components and to ensure that the system behaves as expected. This type of testing is especially important in systems that are composed of multiple components or modules, such as software applications and web services.</p><p><strong>Why Integration Testing is Done</strong></p><p>Integration testing is an important step in the software development process because it helps to identify issues early in the development cycle. This type of testing helps to reduce the risk of defects and to ensure that the system is reliable and of high quality. Integration testing also helps to identify any dependencies between the components and to ensure that the system behaves as expected.</p><p><strong>Benefits of Integration Testing</strong></p><ul><li>Early identification of issues</li><li>Improved reliability and quality</li><li>Better understanding of system behavior</li><li>Improved efficiency and cost-effectiveness</li><li>Reduced risk of defects</li></ul><p><strong>Example of Integration Testing</strong></p><p>An example of integration testing is testing a shopping cart system. The individual components of the system, such as the product catalog, shopping cart, and payment processing module, are tested separately.</p><p>During integration testing, the components are combined and tested as a group to ensure that the interactions between the components work as expected.</p><p><strong>Automation of Integration Testing</strong></p><p>Integration testing can be automated using various tools and languages, such as JUnit, TestNG, and Java. Automated integration testing can help to reduce the time and effort required for manual testing and to increase the efficiency of the testing process.</p><pre>import org.junit.Test;<br>import static org.junit.Assert.assertEquals;<br><br>public class IntegrationTest {<br>  <br>  @Test<br>  public void testIntegration() {<br>    // set up test data<br>    ProductCatalog productCatalog = new ProductCatalog();<br>    ShoppingCart shoppingCart = new ShoppingCart();<br>    PaymentProcessor paymentProcessor = new PaymentProcessor();<br> <br>    // add a product to the shopping cart<br>    Product product = productCatalog.getProduct(&quot;Hoops 3.0 Low Classic Vintage Shoes&quot;);<br>    shoppingCart.addItem(product);<br> <br>    // process payment<br>    paymentProcessor.processPayment(shoppingCart);<br> <br>    // verify that payment was processed successfully<br>    assertEquals(&quot;Success&quot;, shoppingCart.getPaymentStatus());<br>  }<br>}</pre><p>In this code, the IntegrationTest class sets up a Selenium WebDriver to simulate a user’s interactions with a web application, such as navigating to a webpage, entering search keywords, and clicking on search results. The HomePage and SearchResultPage classes define the structure of the web pages and provide methods for interacting with the page elements.</p><p>The setUp method is annotated with @Before, which means it will be run before each test case. The tearDown method is annotated with @After, which means it will be run after each test case. The test Integration method is annotated with @Test, which means it is a test case that will be run by JUnit.</p><p>This integration test uses the Page Object Model design pattern, which allows for a clear separation of concerns between the test code and the page code. The test code is focused on verifying the expected behavior of the application, while the page code is focused on representing the structure of the pages and providing methods for interacting with the pages. This helps to make the test code more readable, maintainable, and reusable.</p><p><strong>Conclusion</strong></p><p>Integration testing is a crucial phase in the software development process that aids in the early detection of issues and ensures that the system performs as planned. Automated integration testing may improve testing process effectiveness and lower mistake risk.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=944f877a836e" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>