Software Testing - Common Testing Techniques (P2)


1. Exploratory Testing – Kiểm thử thăm dò

1.1. Exploratory Testing là gì?

Trong cách kiểm thử truyền thống, tester thường thực hiện theo trình tự:

Thiết kế test case → ghi lại test case → thực thi test case → ghi nhận kết quả.

Exploratory Testing tiếp cận vấn đề theo cách linh hoạt hơn. Theo nội dung bài học, đây là quá trình mà học hỏi, thiết kế kiểm thử và thực thi kiểm thử diễn ra đồng thời. Tester dựa trên những gì vừa quan sát và học được về sản phẩm để quyết định bước kiểm thử tiếp theo.

Tester có thể liên tục tìm hiểu:

  • Sản phẩm hoạt động như thế nào.
  • Thị trường hoặc người dùng mong đợi điều gì.
  • Sản phẩm có thể thất bại theo những cách nào.
  • Những điểm yếu tiềm ẩn của sản phẩm.
  • Cách nào phù hợp để tiếp tục kiểm thử.

Điểm đáng chú ý trong tài liệu là Exploratory Testing không đơn thuần được xem như một kỹ thuật tạo test case, mà là một cách tư duy về kiểm thử.

1.2. Ordinary Testing và Exploratory Testing

Sự khác biệt giữa kiểm thử thông thường và kiểm thử thăm dò có thể nhìn rõ qua cách tổ chức công việc.

Ordinary Testing Exploratory Testing
Test được thiết kế trước Test được thiết kế trong lúc thực hiện
Test case thường được ghi lại Test có thể không được ghi lại đầy đủ
Có thể giao test cho tester khác thực hiện Phụ thuộc nhiều hơn vào người đang khám phá
Nhấn mạnh khả năng kiểm soát và theo dõi Nhấn mạnh khả năng thích ứng và học hỏi

Trong kiểm thử thông thường, người thiết kế test và người chạy test có thể là hai người khác nhau. Ngược lại, trong Exploratory Testing, tester liên tục đưa ra quyết định dựa trên hành vi mà phần mềm vừa thể hiện.

Điều đó không có nghĩa Exploratory Testing là kiểm thử ngẫu nhiên. Tester vẫn cần mục tiêu, tư duy kiểm thử và khả năng quan sát tốt.

1.3. Ba hoạt động chính của Exploratory Testing

Tài liệu mô tả hoạt động của Exploratory Testing theo ba nhóm chính:

Learning – Học hỏi

Tester trước tiên cần khám phá:

  • Các thành phần của sản phẩm.
  • Cách sản phẩm được kỳ vọng hoạt động.
  • Những kỹ thuật thiết kế test có thể áp dụng.

Quá trình học này không kết thúc trước khi test bắt đầu, mà tiếp tục xuyên suốt quá trình kiểm thử.

Design Test Cases – Thiết kế test case

Dựa trên những gì vừa học được, tester:

  • Quyết định thành phần nào cần kiểm thử.
  • Dự đoán những vấn đề chất lượng có thể xảy ra.
  • Lựa chọn kỹ thuật thiết kế kiểm thử thích hợp.

Execute Test Cases – Thực thi

Tester:

  • Cấu hình và vận hành sản phẩm.
  • Quan sát hành vi.
  • So sánh hành vi thực tế với kỳ vọng.

Ba hoạt động này không nhất thiết xảy ra theo một đường thẳng. Tester có thể liên tục quay lại:

Learning → Design → Execute → Learning → Design → Execute...

Đây chính là đặc trưng của Exploratory Testing.


1.4. Heuristic Thinking – Tư duy phỏng đoán

Một yếu tố quan trọng được tài liệu nhắc đến là Heuristic Thinking.

Heuristic có thể hiểu là một ý tưởng hoặc phương pháp hỗ trợ giải quyết vấn đề, dù không đảm bảo luôn đúng trong mọi tình huống.

Trong kiểm thử thăm dò, tester thường đặt câu hỏi liên tục cho hệ thống:

“Nếu tôi thử cách khác thì sao?”

“Điều gì có thể khiến chức năng này thất bại?”

“Tại sao hệ thống lại phản ứng như vậy?”

Tài liệu nhấn mạnh một heuristic nền tảng:

Testing is the process of asking questions of the program.

Ngoài ra còn có ý tưởng rằng nếu tester không còn bất kỳ câu hỏi nào về sản phẩm, môi trường hay khả năng kiểm thử, thì chính việc “không còn câu hỏi” cũng có thể là dấu hiệu cần xem xét lại cách mình đang khám phá hệ thống.

1.5. Khi nào Exploratory Testing hữu ích?

Từ cách tiếp cận trong bài học, Exploratory Testing đặc biệt hữu ích khi tester cần:

  • Làm quen nhanh với một sản phẩm mới.
  • Khám phá các luồng sử dụng chưa được tài liệu hóa rõ.
  • Tìm lỗi ngoài các test case đã có.
  • Phản ứng nhanh với những hành vi bất ngờ.
  • Sử dụng kinh nghiệm của tester để tìm ra những khu vực có rủi ro cao.

Điểm mạnh lớn nhất của phương pháp này là khả năng thích ứng nhanh với những gì tester vừa phát hiện được.

2. Regression Testing – Kiểm thử hồi quy

2.1. Regression Testing là gì?

Trong quá trình phát triển phần mềm, hệ thống liên tục thay đổi:

  • Sửa defect.
  • Thêm chức năng.
  • Chỉnh sửa code.
  • Thay đổi cấu hình.
  • Tối ưu hệ thống.

Một thay đổi tưởng như chỉ ảnh hưởng đến một chức năng có thể vô tình gây lỗi cho những chức năng trước đó đang hoạt động bình thường.

Regression Testing được sử dụng để xác minh rằng:

  • defect đã được sửa đúng,
  • và việc thay đổi phần mềm không tạo ra defect mới ở những khu vực khác.

Điểm quan trọng của Regression Testing không phải là đơn giản chạy lại toàn bộ test case cũ. Vấn đề thực tế là phải quyết định:

Test case nào cần chạy lại?

và:

Có cần tạo thêm test case mới không?

đặc biệt khi thời gian và ngân sách kiểm thử có giới hạn.

2.2. Khi nào thực hiện Regression Testing?

Regression Testing có thể được thực hiện ngay sau khi phần mềm có thay đổi.

Nó không chỉ xuất hiện ở System Testing mà có thể tồn tại trong nhiều mức kiểm thử khác nhau:

  • Unit Testing.
  • Integration Testing.
  • System Testing.

Ở mỗi cấp độ, phạm vi regression sẽ khác nhau.

Ví dụ, nếu một lập trình viên sửa một method trong Java, các unit test liên quan có thể được chạy lại trước. Khi thay đổi được tích hợp với các module khác, nhóm kiểm thử tiếp tục thực hiện regression ở phạm vi rộng hơn.

2.3. Lựa chọn phạm vi Regression Testing

Một trong những khó khăn lớn nhất là lựa chọn test case.

Không phải thay đổi nào cũng cần chạy lại toàn bộ bộ test. Tester cần xem xét khu vực bị ảnh hưởng và lựa chọn phạm vi kiểm thử phù hợp.

Tài liệu đề cập đến các cách tiếp cận regression ở nhiều mức độ, trong đó có việc tập trung vào phần code hoặc chức năng có khả năng bị ảnh hưởng bởi thay đổi thay vì luôn thực hiện full regression.

Có thể hình dung đơn giản:

Thay đổi nhỏ → Regression có trọng tâm

Thay đổi lớn hoặc ảnh hưởng rộng → Regression mở rộng

Việc lựa chọn này giúp cân bằng giữa hai yếu tố:

  • Độ tin cậy.
  • Chi phí kiểm thử.

2.4. Unit Regression Testing

Ở mức đơn vị, regression tập trung vào các hàm, method hoặc component đã được sửa đổi.

Mục tiêu là xác minh:

  • thành phần vừa thay đổi vẫn hoạt động đúng,
  • và thay đổi không phá vỡ hành vi vốn có của chính thành phần đó.

Theo tài liệu, loại kiểm thử này thường gắn với Unit Testing Framework và do lập trình viên thực hiện.

Điều này liên hệ rất tốt với nội dung JUnit đã học trước đó:

Code thay đổi → chạy lại Unit Test → xác minh chức năng cũ vẫn đúng.

2.5. Regression Testing theo hướng rủi ro

Tài liệu còn đề cập Risk-oriented Regression Testing.

Ngoài việc sử dụng lại test case cũ, tester có thể thiết kế test case mới dựa trên những rủi ro phát sinh từ thay đổi.

Ví dụ:

  • Thử thêm các scenario liên quan đến chức năng vừa sửa.
  • Kiểm thử các điều kiện bất thường.
  • Chủ động tìm cách làm chức năng thất bại.

Như vậy, Regression Testing không nên chỉ được hiểu là:

“Chạy lại test cũ.”

Một cách đầy đủ hơn là:

Kiểm tra lại những khu vực có khả năng bị ảnh hưởng bởi thay đổi, đồng thời bổ sung test mới khi rủi ro yêu cầu.

3. Smoke Testing – Kiểm thử nhanh

3.1. Vì sao cần Smoke Testing?

Hãy tưởng tượng nhóm phát triển vừa tạo ra một build mới.

Tester có hai lựa chọn:

Cách 1: lập tức chạy hàng trăm hoặc hàng nghìn test case.

Cách 2: trước tiên kiểm tra nhanh xem những chức năng quan trọng nhất có hoạt động hay không.

Smoke Testing đi theo cách thứ hai.

Mục tiêu là nhanh chóng xác định xem build có đủ ổn định để tiếp tục kiểm thử sâu hơn hay không.

Nếu chức năng cơ bản nhất đã thất bại, việc tiếp tục một bộ kiểm thử dài thường không mang lại nhiều giá trị.

3.2. Bản chất của Smoke Testing

Smoke Testing là một dạng kiểm tra nhanh, tập trung vào những chức năng cốt lõi và nghiêm trọng nhất của hệ thống.

không phải kiểm thử toàn diện.

Nếu smoke test thất bại, đó thường là dấu hiệu cho thấy build đang có vấn đề nghiêm trọng và chưa nên chuyển sang những hoạt động kiểm thử chi tiết hơn.

Tên gọi “Smoke Testing” thường được dùng với ý tưởng tương tự như việc bật một thiết bị lên và quan sát xem có “khói bốc ra” hay không: mục tiêu đầu tiên là phát hiện những lỗi lớn, rõ ràng và có khả năng chặn toàn bộ quá trình kiểm thử.

3.3. Smoke Testing sau thay đổi code

Tài liệu cũng mô tả Smoke Testing theo góc nhìn kiểm tra các thay đổi code trước khi chúng được đưa vào source tree của sản phẩm.

Smoke test giúp xác minh rằng:

  • code vừa thay đổi hoạt động như mong đợi,
  • thay đổi không làm toàn bộ build trở nên không ổn định.

Do đó, Smoke Testing có mối quan hệ khá gần với Regression Testing.

Tuy nhiên, phạm vi Smoke Testing thường nhỏ và nhanh hơn, chỉ nhằm xác nhận rằng build vẫn ở trạng thái đủ tốt để tiếp tục kiểm thử.

3.4. Một số thực hành được đề cập trong tài liệu

Tài liệu đưa ra một số thực hành liên quan đến Smoke Testing:

  • Phối hợp với developer.
  • Code review trước khi smoke test.
  • Sử dụng clean debug build.
  • Tạo daily builds.
  • Thực hiện Smoke Testing trước các hoạt động kiểm thử tiếp theo như web hoặc load testing.

Ý tưởng chung là:

Đừng tiêu tốn nguồn lực kiểm thử sâu cho một build chưa vượt qua được những kiểm tra cơ bản nhất.

4. Mối quan hệ giữa ba kỹ thuật

Ba kỹ thuật của Phần 2 có mục tiêu khác nhau nhưng thường xuất hiện liên tiếp trong cùng một dự án.

Có thể hình dung một tình huống:

Bước 1 – Một build mới được tạo

Nhóm thực hiện Smoke Testing.

Câu hỏi:

“Build này có đủ ổn định để tiếp tục test không?”

Bước 2 – Có chức năng được sửa hoặc thay đổi

Nhóm thực hiện Regression Testing.

Câu hỏi:

“Thay đổi vừa rồi có làm hỏng những chức năng trước đây không?”

Bước 3 – Tester muốn tìm những vấn đề ngoài các test case đã biết

Nhóm sử dụng Exploratory Testing.

Câu hỏi:

“Còn điều gì mà chúng ta chưa nghĩ đến?”

Ba kỹ thuật vì vậy bổ sung cho nhau hơn là thay thế cho nhau.

5. So sánh nhanh ba kỹ thuật

Kỹ thuật Mục tiêu chính Đặc trưng
Exploratory Testing Khám phá lỗi và hiểu sản phẩm Học – thiết kế – thực thi đồng thời
Regression Testing Đảm bảo thay đổi không phá chức năng cũ Chạy lại và bổ sung test dựa trên ảnh hưởng
Smoke Testing Kiểm tra nhanh chất lượng cơ bản của build Ít test case, nhanh, tập trung chức năng cốt lõi

Có thể ghi nhớ ngắn gọn:

Smoke Testing:
Build này có test tiếp được không?

Regression Testing:
Thay đổi này có phá cái cũ không?

Exploratory Testing:
Còn vấn đề nào chúng ta chưa nghĩ tới không?

Tổng kết Phần 2

Phần 2 đưa người học từ tư duy thiết kế test có cấu trúc sang tư duy kiểm thử gần với hoạt động thực tế của một dự án phần mềm.

Exploratory Testing nhấn mạnh khả năng học hỏi, thích ứng và sử dụng kinh nghiệm của tester trong quá trình khám phá hệ thống.

Regression Testing tập trung vào chất lượng phần mềm sau khi có thay đổi, với bài toán quan trọng là xác định phạm vi và test case cần được chạy lại.

Smoke Testing đóng vai trò như một cổng kiểm tra nhanh, giúp xác định build có đủ ổn định để tiếp tục các hoạt động kiểm thử sâu hơn hay không.

Nếu Phần 1 tập trung vào “chúng ta thiết kế test case như thế nào?”, thì Phần 2 tập trung nhiều hơn vào:

“Chúng ta nên kiểm thử như thế nào khi sản phẩm đang được khám phá, sửa đổi và liên tục tạo ra các build mới?”

Phần tiếp theo của bài sẽ chuyển sang nhóm kỹ thuật gần với giai đoạn phát hành sản phẩm: Alpha Testing, Beta Testing và Acceptance Testing.