paint-brush
Bốn kỵ sĩ của những bài kiểm tra dễ vỡby@truuts
1,333
1,333

Bốn kỵ sĩ của những bài kiểm tra dễ vỡ

Eugene Truuts6m2023/10/24
Read on Terminal Reader

Các thử nghiệm tự động hóa không ổn định có thể là một trở ngại đối với các kỹ sư QA, gây ra sự không chắc chắn và làm suy yếu độ tin cậy của các bộ thử nghiệm. Rút kinh nghiệm từ kinh nghiệm của tôi với tư cách là người cố vấn SDET và QA Automation, bài viết này đưa ra lời khuyên thiết thực để khắc phục tình trạng không ổn định. Mặc dù tôi sẽ cung cấp các ví dụ về JavaScript và Nhà viết kịch, nhưng những mẹo phổ quát này có thể áp dụng được bằng mọi ngôn ngữ và khung công tác, giúp bạn viết các bài kiểm tra tự động hóa mạnh mẽ và đáng tin cậy. Hãy đi sâu vào và đảm bảo bài kiểm tra của bạn ổn định.
featured image - Bốn kỵ sĩ của những bài kiểm tra dễ vỡ
Eugene Truuts HackerNoon profile picture
0-item
1-item


Các thử nghiệm tự động hóa không ổn định có thể là một trở ngại đối với các kỹ sư QA, gây ra sự không chắc chắn và làm suy yếu độ tin cậy của bộ thử nghiệm. Rút kinh nghiệm từ kinh nghiệm của tôi với tư cách là người cố vấn SDET và QA Automation, bài viết này đưa ra lời khuyên thiết thực để khắc phục tình trạng không ổn định. Mặc dù tôi sẽ cung cấp các ví dụ về JavaScript và Nhà viết kịch, nhưng những mẹo phổ quát này có thể áp dụng được bằng mọi ngôn ngữ và khung làm việc, giúp bạn viết các bài kiểm tra tự động hóa mạnh mẽ và đáng tin cậy. Hãy đi sâu vào và đảm bảo bài kiểm tra của bạn đứng vững.

1. Tránh các phương pháp chờ đợi ngầm

Đôi khi, bạn sẽ gặp phải tình huống phải đợi các phần tử xuất hiện trong DOM hoặc chờ ứng dụng của bạn đạt đến trạng thái cụ thể để tiếp tục kịch bản thử nghiệm của mình. Ngay cả với các khung tự động hóa thông minh, hiện đại như tính năng tự động chờ của Playwright, sẽ có những trường hợp bạn cần triển khai các phương pháp chờ tùy chỉnh. Ví dụ: hãy xem xét một tình huống có trường văn bản và nút xác nhận. Do hành vi cụ thể của phía máy chủ, nút xác nhận chỉ hiển thị sau khoảng năm giây hoàn thành biểu mẫu. Trong những trường hợp như vậy, việc chống lại sự cám dỗ của việc chèn khoảng thời gian chờ ngầm năm giây giữa hai bước kiểm tra là điều cần thiết.


 textField.fill('Some text') waitForTime(5000) confirmationButton.click()


Thay vào đó hãy sử dụng một cách tiếp cận thông minh và chờ đợi trạng thái chính xác. Nó có thể là phần tử văn bản xuất hiện sau một số lần tải hoặc phần tử quay của trình tải biến mất sau khi bước hiện tại được thực hiện thành công. Bạn có thể kiểm tra xem bạn đã sẵn sàng cho bước kiểm tra tiếp theo chưa.


 button.click() waitFor(textField.isVisible()) textField.fill()


Tất nhiên, có những trường hợp bạn cần chờ đợi điều gì đó mà bạn không thể kiểm tra một cách thông minh. Tôi khuyên bạn nên thêm nhận xét ở những nơi như vậy hoặc thậm chí thêm phần giải thích lý do làm tham số trong phương thức chờ của bạn hoặc đại loại như thế:


 waitForTime(5000, {reason: "For unstable server processed something..."}


Một lợi ích bổ sung khi sử dụng nó là các báo cáo thử nghiệm, nơi bạn có thể lưu trữ những lời giải thích như vậy để người khác hoặc thậm chí cho bạn biết rõ điều gì và tại sao trong 5 giây như vậy lại chờ đợi ở đây trong tương lai.


 waitForTime(5000, {reason: "For unstable server processed something..."} button.click() waitFor(textField.isVisible()) textField.fill()

2. Sử dụng các công cụ định vị mạnh mẽ và đáng tin cậy để chọn các phần tử

Bộ định vị là một phần quan trọng của thử nghiệm tự động hóa và mọi người đều biết điều đó. Tuy nhiên, bất chấp thực tế đơn giản này, nhiều kỹ sư tự động hóa đang cố gắng đảm bảo tính ổn định và sử dụng những thứ như thế này trong các thử nghiệm của họ.


 //*[@id="editor_7"]/section/div[2]/div/h3[2]


Đó là một cách tiếp cận ngớ ngẩn vì cấu trúc DOM không quá tĩnh; một số nhóm khác nhau đôi khi có thể thay đổi nó và điều này xảy ra sau khi thử nghiệm của bạn thất bại. Vì vậy, hãy sử dụng các bộ định vị mạnh mẽ. Nhân tiện, bạn được chào đón đến với việc đọc câu chuyện liên quan đến XPath của tôi.



3. Thực hiện các bài kiểm tra độc lập với nhau

Khi chạy bộ thử nghiệm với nhiều thử nghiệm trong một luồng duy nhất, điều quan trọng là phải đảm bảo mỗi thử nghiệm là độc lập. Điều này có nghĩa là lần kiểm tra đầu tiên sẽ đưa hệ thống về trạng thái ban đầu để lần kiểm tra tiếp theo không bị lỗi do các điều kiện không mong muốn. Ví dụ: nếu một trong các thử nghiệm của bạn sửa đổi cài đặt người dùng được lưu trữ trong LocalStorage thì việc xóa mục nhập LocalStorage cho Cài đặt người dùng sau lần chạy thử nghiệm đầu tiên là một cách tiếp cận tốt. Điều này đảm bảo rằng thử nghiệm thứ hai sẽ được thực hiện với cài đặt người dùng mặc định. Bạn cũng có thể xem xét các hành động như đặt lại trang về trang nhập mặc định và xóa cookie cũng như mục nhập cơ sở dữ liệu để mỗi lần kiểm tra mới bắt đầu với các điều kiện ban đầu giống hệt nhau.


Ví dụ: trong Playwright, bạn có thể sử dụng các chú thích beforeAll(), beforeEach(), afterAll() và afterEach() để đạt được điều đó.


Kiểm tra bộ thử nghiệm tiếp theo với một vài thử nghiệm. Đầu tiên là thay đổi cài đặt giao diện của người dùng và thứ hai là kiểm tra giao diện mặc định.


 test.describe('Test suite', () => { test('TC101 - update appearance settings to dark', async ({page}) => { await user.goTo(views.settings); await user.setAppearance(scheme.dark); }); test('TC102 - check if default appearance is light', async ({page}) => { await user.goTo(views.settings); await user.checkAppearance(scheme.light); }); });


Nếu bộ thử nghiệm như vậy chạy song song thì mọi thứ sẽ diễn ra suôn sẻ. Tuy nhiên, nếu các bài kiểm tra này được thực hiện lần lượt, bạn có thể gặp phải một bài kiểm tra thất bại vì một trong số chúng đang can thiệp vào bài kiểm tra khác. Thử nghiệm đầu tiên đã thay đổi diện mạo từ sáng sang tối. Thử nghiệm thứ hai sẽ kiểm tra xem bề ngoài hiện tại có sáng sủa hay không. Nhưng nó sẽ thất bại vì lần thử nghiệm đầu tiên đã thay đổi giao diện mặc định rồi.

Để giải quyết vấn đề như vậy, tôi đã thêm hook afterEach() được thực thi sau mỗi lần kiểm tra. Trong trường hợp này, nó sẽ điều hướng đến chế độ xem mặc định và xóa giao diện của người dùng bằng cách xóa nó khỏi Bộ nhớ cục bộ.


 test.afterEach(async ({ page }) => { await user.localStorage(appearanceSettings).clear() await user.goTo(views.home) }); test.describe('Test suite', () => { test('TC101 - update appearance settings to dark', async ({page}) => { await user.goto(views.settings); await user.setAppearance(scheme.dark); }); test('TC102 - check if default appearance is light', async ({page}) => { await user.goTo(views.settings); await user.checkAppearance(scheme.light); }); });


Sử dụng phương pháp này, mỗi bài kiểm tra trong bộ này sẽ độc lập.


4. Sử dụng tính năng thử lại tự động một cách khôn ngoan

Không ai tránh khỏi việc gặp phải các thử nghiệm không ổn định và một biện pháp khắc phục phổ biến cho vấn đề này là sử dụng thử lại. Bạn có thể định cấu hình việc thử lại diễn ra tự động, ngay cả ở cấp cấu hình CI/CD. Ví dụ: bạn có thể thiết lập số lần thử lại tự động cho mỗi lần kiểm tra không thành công, chỉ định số lần thử lại tối đa là ba lần. Bất kỳ thử nghiệm nào ban đầu không thành công sẽ được thử lại tối đa ba lần cho đến khi chu trình thực hiện thử nghiệm hoàn tất. Ưu điểm là nếu bài kiểm tra của bạn chỉ hơi sai sót một chút thì nó có thể vượt qua sau một vài lần thử lại.


Tuy nhiên, nhược điểm là nó có thể bị lỗi, dẫn đến tiêu tốn thêm thời gian chạy. Hơn nữa, cách làm này có thể vô tình dẫn đến việc tích lũy các bài kiểm tra không ổn định, vì nhiều bài kiểm tra có vẻ “vượt qua” ở lần thử thứ hai hoặc thứ ba và bạn có thể gắn nhãn sai cho chúng là ổn định. Do đó, tôi khuyên bạn không nên đặt tự động thử lại trên toàn cầu cho toàn bộ dự án thử nghiệm của mình. Thay vào đó, hãy thử lại một cách có chọn lọc trong trường hợp bạn không thể giải quyết kịp thời các vấn đề cơ bản trong quá trình kiểm tra.


Ví dụ: giả sử bạn có một trường hợp thử nghiệm trong đó bạn phải tải lên một số tệp bằng sự kiện 'filechooser'. Bạn nhận được lỗi <Đã vượt quá thời gian chờ trong khi chờ đợi sự kiện 'filechooser'>, điều này cho biết rằng quá trình kiểm tra Playwright đang chờ sự kiện 'filechooser' xảy ra nhưng mất nhiều thời gian chờ hơn.


 async function uploadFile(page: Page, file) { const fileChooserPromise = page.waitForEvent('filechooser'); await clickOnElement(page, uploadButton); const fileChooser = await fileChooserPromise; await fileChooser.setFiles(file); }


Điều này có thể do nhiều lý do khác nhau, chẳng hạn như hành vi không mong muốn trong ứng dụng hoặc môi trường chậm. Vì đây là hành vi ngẫu nhiên nên điều đầu tiên bạn có thể nghĩ đến là sử dụng tính năng thử lại tự động cho bài kiểm tra này. Tuy nhiên, nếu bạn thử lại toàn bộ bài kiểm tra, bạn có nguy cơ lãng phí thêm thời gian và gặp phải hành vi tương tự như lỗi đầu tiên trong chính phương thức uploadFile(), vì vậy nếu lỗi xảy ra, bạn không cần phải thử lại toàn bộ bài kiểm tra.


Để làm điều này, bạn có thể sử dụng câu lệnh try…catch tiêu chuẩn.


 async function uploadFile(page: Page, file) { const maxRetries = 3; let retryCount = 0; while (retryCount < maxRetries) { try { const fileChooserPromise = page.waitForEvent('filechooser'); await clickOnElement(page, uploadButton); const fileChooser = await fileChooserPromise; await fileChooser.setFiles(file); break; // Success, exit the loop } catch (error) { console.error(`Attempt ${retryCount + 1} failed: ${error}`); retryCount++; } } }


Cách tiếp cận như vậy sẽ tiết kiệm thêm thời gian và làm cho bài kiểm tra của bạn bớt sai sót hơn.


Tóm lại, con đường dẫn đến các thử nghiệm tự động hóa đáng tin cậy rất đơn giản. Bạn có thể giảm thiểu hoặc chủ động giải quyết những thách thức chung và thực hiện các chiến lược thông minh. Hãy nhớ rằng, hành trình này vẫn đang diễn ra và các bài kiểm tra của bạn sẽ trở nên đáng tin cậy hơn nếu bạn kiên trì. Nói lời tạm biệt với sự bong tróc và chào đón sự ổn định. Cam kết của bạn về chất lượng đảm bảo sự thành công của dự án. Chúc bạn thử nghiệm vui vẻ!


Cũng được xuất bản ở đây .