Kiểm thử tự động có thể chạy song song trên nhiều môi trường, nhiều trình duyệt, nhiều thiết bị và nhiều bộ dữ liệu.
Các thử nghiệm này ít xảy ra lỗi do con người hơn so với các thử nghiệm thủ công, điều này có thể giúp cải thiện độ chính xác và độ tin cậy của quy trình thử nghiệm. Hơn nữa, chúng có thể lặp lại, nhất quán và đáng tin cậy giúp giảm các kết quả dương tính giả và âm tính giả. Trong bài viết này, tôi sẽ nói về lý do tại sao bạn nên sử dụng các bài kiểm tra tự động trong Selenium, JUnit5 và Gauge Framework.
Tăng hiệu quả
Kiểm thử tự động có thể chạy nhanh hơn so với kiểm thử thủ công, cho phép chạy nhiều kiểm thử hơn trong một khoảng thời gian ngắn hơn. Điều này có thể giúp xác định các vấn đề và lỗi nhanh hơn, tiết kiệm thời gian và tài nguyên về lâu dài. Các thử nghiệm tự động hóa có thể chạy song song trên nhiều môi trường, nhiều trình duyệt, nhiều thiết bị và nhiều bộ dữ liệu, giúp tăng hiệu quả tổng thể của quy trình thử nghiệm.
import com.thoughtworks.gauge.Step import org.openqa.selenium.By import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver class AutomationTest { private lateinit var driver: WebDriver @Step("Open the browser and navigate to the website") fun openBrowser() { System.setProperty("webdriver.chrome.driver", "/path/to/chrome/driver") driver = ChromeDriver() driver.get("https://www.example.com") } @Step("Search for <searchTerm>") fun search(searchTerm: String) { driver.findElement(By.name("q")).sendKeys(searchTerm) driver.findElement(By.name("btnK")).click() } @Step("Close the browser") fun closeBrowser() { driver.quit() } }
Đây là một ví dụ về tập lệnh tự động hóa thử nghiệm đơn giản được viết bằng Kotlin đang sử dụng thư viện Selenium để tương tác với trang web và khung Gauge để tổ chức và chạy thử nghiệm. Tập lệnh này sẽ mở một trình duyệt, điều hướng đến một trang web, thực hiện tìm kiếm rồi đóng trình duyệt.
Bởi vì thử nghiệm này được tự động hóa, nên nó có thể chạy nhanh hơn nếu được thực hiện thủ công.
Đây chỉ là một ví dụ đơn giản, trong trường hợp sử dụng trong thế giới thực, bạn có thể có nhiều kịch bản, nhiều trường hợp thử nghiệm và nhiều bộ thử nghiệm có thể được tự động hóa và chạy song song, giúp tăng hiệu quả tổng thể của quy trình thử nghiệm.
Cần lưu ý rằng, nếu bạn đang làm việc với một ứng dụng web, thì có các khung và công cụ khác có thể được sử dụng cùng với hoặc thay vì Selenium, chẳng hạn như Cypress, WebDriverIO và TestCafe, mỗi khung có các tính năng và ưu điểm riêng .
Cải thiện độ chính xác
Thử nghiệm tự động ít xảy ra lỗi do con người gây ra hơn so với thử nghiệm thủ công, điều này có thể giúp cải thiện độ chính xác và độ tin cậy của quy trình thử nghiệm. Các xét nghiệm tự động có thể lặp lại, nhất quán và đáng tin cậy giúp giảm thiểu kết quả dương tính giả và âm tính giả.
import com.thoughtworks.gauge.Step import org.openqa.selenium.By import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver class AutomationTest { private lateinit var driver: WebDriver @Step("Open the browser and navigate to the website") fun openBrowser() { System.setProperty("webdriver.chrome.driver", "/path/to/chrome/driver") driver = ChromeDriver() driver.get("https://www.example.com") } @Step("Search for <searchTerm> and verify the result") fun search(searchTerm: String) { driver.findElement(By.name("q")).sendKeys(searchTerm) driver.findElement(By.name("btnK")).click() val searchResult = driver.findElement(By.xpath("//div[@class='g']")) assert(searchResult.text.contains(searchTerm)) } @Step("Close the browser") fun closeBrowser() { driver.quit() } }
Trong ví dụ này, tập lệnh không chỉ thực hiện tìm kiếm mà còn xác minh kết quả bằng cách khẳng định rằng kết quả tìm kiếm được trả về có chứa cụm từ tìm kiếm. Điều này giúp đảm bảo kiểm tra chính xác và sẽ phát hiện mọi sự cố có thể xảy ra với chức năng tìm kiếm.
Vì tập lệnh được tự động hóa nên tập lệnh sẽ chạy theo cùng một cách mỗi khi được thực thi với cùng một đầu vào, đảm bảo thử nghiệm có thể lặp lại, nhất quán và đáng tin cậy. Điều này giúp giảm thiểu kết quả dương tính giả và âm tính giả, có thể xảy ra với thử nghiệm thủ công.
Ngoài ra, bạn có thể sử dụng các công cụ báo cáo kiểm tra như báo cáo Gauge, Allure, TestNG, JUnit, v.v. để theo dõi kết quả kiểm tra, cho phép bạn biết liệu kiểm tra có đạt hay không. Nếu thất bại, nó sẽ tiết lộ lý do đằng sau thất bại, giúp xác định sớm các vấn đề trong quá trình phát triển và ngăn chúng trở thành vấn đề nghiêm trọng hơn sau này.
3. Cho phép kiểm tra thường xuyên
Các thử nghiệm tự động có thể được chạy thường xuyên, chẳng hạn như mỗi khi thay đổi mã được thực hiện, điều này có thể giúp xác định sớm các vấn đề trong quá trình phát triển và ngăn chúng trở thành các vấn đề nghiêm trọng hơn sau này. Điều này hỗ trợ bắt lỗi sớm trong chu kỳ phát triển và giúp giảm chi phí chung cho việc sửa lỗi.
import com.thoughtworks.gauge.Step import org.openqa.selenium.By import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver import org.junit.jupiter.api.Test import org.junit.jupiter.api.BeforeEach class AutomationTest { private lateinit var driver: WebDriver @BeforeEach fun openBrowser() { System.setProperty("webdriver.chrome.driver", "/path/to/chrome/driver") driver = ChromeDriver() driver.get("https://www.example.com") } @Test fun testSearch() { driver.findElement(By.name("q")).sendKeys("searchTerm") driver.findElement(By.name("btnK")).click() val searchResult = driver.findElement(By.xpath("//div[@class='g']")) assert(searchResult.text.contains("searchTerm")) } @AfterEach fun closeBrowser() { driver.quit() } }
Tập lệnh này sử dụng khung JUnit5 và chú thích @Test
, đánh dấu một phương thức là một phương thức thử nghiệm. Điều này cho phép thử nghiệm được chạy tự động như một phần của bộ thử nghiệm. Ngoài ra, tập lệnh sử dụng các chú thích @BeforeEach
và @AfterEach
đánh dấu một phương thức sẽ được thực thi trước hoặc sau mỗi phương thức thử nghiệm.
Bạn cũng có thể sử dụng quy trình CI/CD và tích hợp thử nghiệm tự động hóa với nó, cho phép chạy thử nghiệm tự động như một phần của quy trình xây dựng và với mỗi lần thay đổi mã. Điều này giúp đảm bảo rằng các thay đổi mã được kiểm tra và có chất lượng tốt trước khi được triển khai vào sản xuất.
4. Tiết kiệm chi phí
Các thử nghiệm tự động có thể chạy mà không cần sự can thiệp của con người, giúp giảm chi phí thử nghiệm theo thời gian. Kiểm thử tự động có thể được chạy thường xuyên và có thể được lên lịch để chạy vào một thời điểm cụ thể giúp giảm nhu cầu về nguồn nhân lực.
import com.thoughtworks.gauge.Step import org.openqa.selenium.By import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver import org.junit.jupiter.api.Test import org.junit.jupiter.api.BeforeEach class AutomationTest { private lateinit var driver: WebDriver @BeforeEach fun openBrowser() { System.setProperty("webdriver.chrome.driver", "/path/to/chrome/driver") driver = ChromeDriver() driver.get("https://www.example.com") } @Test fun testSearch() { driver.findElement(By.name("q")).sendKeys("searchTerm") driver.findElement(By.name("btnK")).click() val searchResult = driver.findElement(By.xpath("//div[@class='g']")) assert(searchResult.text.contains("searchTerm")) } @Test fun testSignUp() { driver.findElement(By.linkText("Sign Up")).click() driver.findElement(By.name("username")).sendKeys("myusername") driver.findElement(By.name("password")).sendKeys("mypassword") driver.findElement(By.name("submit")).click() val message = driver.findElement(By.xpath("//div[@class='message']")) assert(message.text.contains("Welcome myusername")) } @AfterEach fun closeBrowser() { driver.quit() } }
Trong ví dụ này, chúng tôi có hai trường hợp thử nghiệm. Cái đầu tiên là để kiểm tra chức năng tìm kiếm và cái thứ hai là để kiểm tra chức năng đăng ký. Bằng cách có nhiều trường hợp thử nghiệm trong một tập lệnh, nó sẽ tăng hiệu quả tổng thể của quy trình thử nghiệm, điều này có thể giúp giảm chi phí thử nghiệm tổng thể.
Ngoài ra, bạn có thể sử dụng tham số hóa thử nghiệm để chạy cùng một trường hợp thử nghiệm với nhiều đầu vào và tập dữ liệu. Điều này làm tăng phạm vi kiểm tra tổng thể và giúp tìm ra nhiều lỗi hơn, giảm chi phí kiểm tra tổng thể.
Ngoài ra, bạn có thể sử dụng các môi trường thử nghiệm dựa trên đám mây như SauceLabs, BrowserStack và TestingBot, cho phép bạn chạy thử nghiệm trên nhiều trình duyệt và hệ điều hành mà không phải duy trì cơ sở hạ tầng thử nghiệm của riêng mình. Điều này có thể giảm chi phí liên quan đến việc duy trì và mở rộng cơ sở hạ tầng thử nghiệm.
Nhìn chung, các thử nghiệm tự động có thể tiết kiệm chi phí bằng cách giảm nhu cầu về nguồn nhân lực, tăng hiệu quả của quy trình thử nghiệm và bằng cách sử dụng các môi trường thử nghiệm dựa trên đám mây.
5. Tăng phạm vi bảo hiểm
Thử nghiệm tự động có thể bao gồm nhiều tình huống, đầu vào và trường hợp sử dụng khó bao quát thủ công, do đó tăng phạm vi bao phủ tổng thể của thử nghiệm. Kiểm thử tự động có thể bao gồm các trình duyệt khác nhau, các thiết bị khác nhau, các phiên bản khác nhau của hệ điều hành, các bộ dữ liệu khác nhau và các tình huống khác nhau, điều này làm tăng phạm vi kiểm thử tổng thể.
import com.thoughtworks.gauge.Step import org.openqa.selenium.By import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver import org.junit.jupiter.api.Test import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.CsvSource class AutomationTest { private lateinit var driver: WebDriver @BeforeEach fun openBrowser() { System.setProperty("webdriver.chrome.driver", "/path/to/chrome/driver") driver = ChromeDriver() driver.get("https://www.example.com") } @ParameterizedTest @CsvSource(value = ["searchTerm1, expectedResult1", "searchTerm2, expectedResult2", "searchTerm3, expectedResult3"]) fun testSearch(searchTerm: String, expectedResult: String) { driver.findElement(By.name("q")).sendKeys(searchTerm) driver.findElement(By.name("btnK")).click() val searchResult = driver.findElement(By.xpath("//div[@class='g']")) assert(searchResult.text.contains(expectedResult)) } @AfterEach fun closeBrowser() { driver.quit() } }
Trong ví dụ này, chúng tôi đang sử dụng chú thích JUnit5 @ParameterizedTest
và @CsvSource
để chạy cùng một trường hợp thử nghiệm với nhiều đầu vào, tăng phạm vi thử nghiệm tổng thể. Thử nghiệm sẽ chạy ba lần với các giá trị đầu vào khác nhau và mỗi lần nó sẽ kiểm tra xem đầu ra có khớp với kết quả mong đợi hay không.
Bằng cách này, bạn có thể kiểm tra cùng một chức năng với nhiều bộ dữ liệu, giúp tìm ra nhiều lỗi hơn và tăng phạm vi kiểm tra tổng thể. Ngoài ra, bạn cũng có thể sử dụng các khung kiểm thử dựa trên dữ liệu như TestNG, JUnit5, v.v. để chạy các trường hợp kiểm thử với nhiều đầu vào, tăng phạm vi kiểm thử tổng thể.
6. Cải thiện tính nhất quán Các thử nghiệm tự động luôn chạy theo cùng một cách, đảm bảo các vấn đề giống nhau không bị bỏ sót nhiều lần. Các xét nghiệm tự động có thể lặp lại, nhất quán và đáng tin cậy giúp giảm các kết quả dương tính giả và âm tính giả.
import com.thoughtworks.gauge.Step import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response class API_AutomationTest { @Step("GET request to <endpoint> and verify the response") fun testAPI(endpoint: String) { val client = OkHttpClient() val request = Request.Builder() .url(endpoint) .get() .build() val response = client.newCall(request).execute() val json = response.body()?.string() assert(json!!.contains("\"userId\": 1")) } }
Tập lệnh này sử dụng khung Gauge và chú thích @Step
, đánh dấu một phương thức là một bước trong kịch bản thử nghiệm. Điều này cho phép kịch bản thử nghiệm được viết ở định dạng dễ đọc và dễ hiểu, làm cho quy trình thử nghiệm trở nên dễ hiểu.
Bạn cũng có thể sử dụng khái niệm thử nghiệm theo hướng dữ liệu của máy đo, trong đó bạn có thể chạy cùng một kịch bản thử nghiệm với nhiều đầu vào, tăng phạm vi thử nghiệm tổng thể và có khả năng tìm thấy nhiều lỗi hơn.
Ngoài ra, bạn có thể sử dụng khả năng báo cáo của máy đo, cung cấp báo cáo rõ ràng và ngắn gọn về các kịch bản thử nghiệm, kết quả thử nghiệm và thời gian thực hiện thử nghiệm.
7. Cho phép tích hợp liên tục và phân phối liên tục
Kiểm thử tự động là một công cụ hỗ trợ chính để tích hợp và phân phối liên tục, đây là một khía cạnh quan trọng của quá trình phát triển phần mềm hiện đại. Các thử nghiệm tự động có thể được tích hợp với quy trình CI/CD và có thể chạy tự động trên mọi thay đổi mã, đảm bảo các thay đổi mã được kiểm tra và có chất lượng tốt trước khi được triển khai vào sản xuất.
Bạn có thể sử dụng quy trình CI/CD và tích hợp tập lệnh với nó, cho phép chạy thử nghiệm tự động như một phần của quy trình xây dựng và với mỗi lần thay đổi mã.
Ví dụ: bạn có thể sử dụng Jenkins, Travis, CircleCI, v.v. làm công cụ CI/CD. Sau đó, bạn có thể thiết lập công việc để xây dựng dự án, chạy các trường hợp thử nghiệm và triển khai ứng dụng vào sản xuất nếu các thử nghiệm vượt qua.
Đây là một khía cạnh quan trọng của phát triển phần mềm hiện đại và nó giúp đạt được việc cung cấp phần mềm nhanh hơn và đáng tin cậy hơn.
pipeline { agent any stages { stage('Build') { steps { sh './gradlew build' } } stage('Test') { steps { sh 'gauge run specs/' } } stage('Deploy') { steps { sh './deploy.sh' } } } }
Jenkinsfile này xác định một quy trình có ba giai đoạn: Xây dựng, Thử nghiệm và Triển khai.
Trong giai đoạn Build , đường ống chạy lệnh './gradlew build'. Lệnh này sẽ xây dựng dự án và tạo các tạo phẩm cần thiết.
Trong giai đoạn Kiểm tra , đường ống chạy lệnh 'thông số kỹ thuật chạy máy đo/'. Lệnh này sẽ thực hiện tất cả các trường hợp kiểm tra máy đo trong thư mục thông số kỹ thuật.
Trong giai đoạn Triển khai , đường dẫn chạy lệnh './deploy.sh'. Lệnh này sẽ triển khai ứng dụng vào môi trường sản xuất.
Bạn có thể thiết lập công việc Jenkins để chạy Jenkinsfile này và nó sẽ xây dựng, kiểm tra và triển khai ứng dụng nếu vượt qua các bài kiểm tra.
Với ví dụ này, bạn có thể thấy cách bạn có thể sử dụng các bài kiểm tra Gauge trong Jenkinsfile để cho phép tích hợp liên tục và phân phối liên tục. Điều này cho phép bạn tự động hóa quá trình thử nghiệm.
Tăng hiệu quả bằng cách cho phép chạy nhiều trường hợp thử nghiệm trong một tập lệnh.
Cải thiện độ chính xác bằng cách giảm lỗi của con người và cung cấp kết quả nhất quán.
Cho phép kiểm tra thường xuyên bằng cách giúp dễ dàng chạy kiểm tra thường xuyên.
Có hiệu quả về chi phí bằng cách giảm tổng chi phí thử nghiệm và tăng phạm vi thử nghiệm.
Tăng mức độ phù hợp bằng cách cho phép chạy cùng một trường hợp thử nghiệm với nhiều đầu vào và bộ dữ liệu.
Cải thiện tính nhất quán bằng cách đảm bảo rằng phần mềm đang hoạt động như mong đợi.
Cho phép Tích hợp liên tục và Phân phối liên tục bằng cách cho phép chạy thử nghiệm tự động như một phần của quy trình xây dựng và với mỗi thay đổi mã, đảm bảo các thay đổi mã được kiểm tra và có chất lượng tốt trước khi được triển khai vào sản xuất.
Nhìn chung, kiểm thử tự động giúp cải thiện chất lượng tổng thể của phần mềm, giảm chi phí kiểm thử tổng thể, tăng phạm vi kiểm thử, cải thiện tính nhất quán và cho phép tích hợp liên tục và phân phối liên tục dẫn đến phân phối phần mềm nhanh hơn và đáng tin cậy hơn.