Tổng quan về TDD-BDD & kiểm thử phần mềm trong mô hình Agile từ góc nhìn của một Acceptance Tester

Một tester chuyên nghiệp – có thể nói nhu cầu hiểu biết về các mô hình phát triển phần mềm tiên tiến là một nhu cầu bức thiết. Với mong muốn chia sẻ và trau dồi thông tin, mình xin gửi đến các bạn đọc giả của hoidapit một số hiểu biết của mình về Test-Driven Development (TDD) và Behavior-Driven Development (BDD) – mô hình phát triển phần mềm hướng kiểm thử (test oriented) theo tinh thần Agile – đã và đang được áp dụng rộng rãi.
1. TDD là gì?

Mô hình "Test – Driven Development " (TDD). Trong quy trình này, kiểm thử đơn vị được viết đầu tiên do các kỹ sư phần mềm (thường là lập trình song song trong các phương pháp lập trình Extreme). Tất nhiên những kiểm thử bước đầu thất bại như dự kiến, nhưng sau đó Code được viết xong thì phần lớn các Test Suite sẽ từng bước tăng lên. Nó được cập nhật như là các lỗi điều kiện mới và các trường hợp tiềm ẩn vừa được phát hiện ra, chúng được tích hợp với bất kỳ kiểm thử hồi quy nào được phát triển. Kiểm thử đơn vị được duy trì cùng với phần còn lại của các mã nguồn phần mềm và được tích hợp chung vào quá trình xây dựng (với những kiểm thử tương tác vốn đã bị loại bỏ quá trình xây dựng mức chấp nhận thông thường). Mục tiêu cuối cùng của quá trình kiểm thử này là để đạt được việc triển khai liên tục mà ở đó những cập nhật phần mềm có thể được công bố cho công chúng thường xuyên.
Phương pháp này làm tăng các nỗ lực kiểm thử trước khi động đến bất kỳ nhóm kiểm thử chính thức. Trong một số mô hình phát triển khác, hầu hết việc thực hành các kiểm thử xảy ra sau khi các yêu cầu đã được xác định và quá trình mã hóa đã được hoàn thành.
Chính xác với nghĩa đen của nó: “Test-Driven Development” có thể được tạm hiểu là mô hình phát triển với trọng tâm hướng về việc kiểm thử. TDD được xây dựng theo hai tiêu chí: Test-First (Kiểm thử trước) và Refactoring (Điều chỉnh mã nguồn). Trong đó, khi một yêu cầu phần mềm (requirement) được đặt ra:

-  
Người developer soạn thảo kịch bản kiểm thử (test case) cho yêu cầu đó trước tiên và chạy thử kịch bản đó lần đầu tiên. Hiển nhiên, việc chạy thử sẽ đưa ra 1 kết quả thất bại vì hiện tại chức năng đó chưa được xây dựng (và thông qua kết quả đó, ta cũng kiểm tra được là kịch bản kiểm thử đó được viết đúng).

-  Theo đó, dựa vào mong muốn (expectation) của kịch bản kia, người developer sẽ xây dựng một lượng mã nguồn (source code) vừa đủ để lần chạy thứ 2 của kịch bản đó thành công.

-  Nếu trong lần chạy thứ 2 vẫn đưa ra 1 kết quả thất bại, điều đó có nghĩa là thiết kế chưa ổn và người developer lại chỉnh sửa mã nguồn và chạy lại kịch bản đến khi thành công.

-  Khi kịch bản kiểm thử được chạy thành công, người developer tiến hành chuẩn hóa đoạn mã nguồn (base-line code) và tiếp tục hồi quy với kịch bản kiểm thử tiếp theo. Việc chuẩn hóa bao gồm thêm các comment, loại bỏ các dư thừa, tối ưu các biến…


Quy trình phát triển TDD vẽ bởi Colin Kloes, đề cập vấn đề khó khăn trong việc hiểu rõ yêu cầu chức năng trước khi viết kịch bản kiểm thử
2. Điểm khác biệt của TDD với một mô hình truyền thống là gì?
Thông qua quy trình TDD trình bày ở trên, ta có thể dễ dàng nhận ra là thứ tự các bước xây dựng 1 tính năng phần mềm gần như đã được đảo ngược so với 1 quy trình truyền thống. Vậy điều này giúp ích gì và có gì hay hơn?

Trước hết, hãy nhìn lại 1 mô hình thác đổ (Waterfall Model) thông thường: việc phân tích các yêu cầu (requirements) thường được tiến hành bởi Business Analyst (BA) 1 cách chuyên hóa và khi đến giai đoạn xây dựng (implementing phase) thì đa phần các developer tiếp xúc với các yêu cầu phần mềm dưới dạng các bản thiết kế. Họ chỉ quan tâm đến đầu vào, đầu ra (Input, Output) của tính năng mình xây dựng mà thiếu đi cái nhìn thực tiễn từ góc nhìn người dùng (end-users). Một hệ quả tất yếu là lỗi phần mềm đến từ việc sản phẩm ko tiện dụng với người dùng.

Cùng với Agile, việc ứng dụng TDD góp phần làm gần khoảng cách giữa đội ngũ thiết kế phần mềm và sản phẩm thực tiễn, tối ưu quy trình [2]. Cụ thể như sau:

-  Thông qua kịch bản kiểm thử, developer có cái nhìn trực quan về sản phẩm ngay trước khi xây dựng mã nguồn. Sản phẩm họ tạo ra chính xác và gần gũi người dùng hơn.

-  Phần mã nguồn được thêm vào chỉ vừa đủ để chạy thành công kịch bản kiểm thử, hạn chế dư thừa và qua đó hạn chế khả năng xảy ra lỗi trên những phần dư thừa.

-  Bảo đảm mã nguồn luôn phản ánh đúng và vừa đủ yêu cầu phần mềm, hạn chế được công sức tối ưu mã nguồn về sau.

3. TDD và Agile
Trong quá trình hình thành, TDD có liên quan mật thiết đến khái niệm “Test-First Programming” trong mô hình eXtreme Programming “XP” thuần túy Agile – thịnh hành từ năm 1999. Tuy nhiên, bằng việc ứng dụng đa dạng và linh hoạt, TDD cũng có những đặc điểm và tùy biến của riêng nó (mình sẽ trình bày rõ hơn bên dưới).
TDD đáp ứng “Tuyên ngôn về Agile” khi bản thân quy trình TDD thúc đẩy tính thực tiễn của sản phẩm, tương tác với người dùng. Để phát huy tối đa những lợi ích mà TDD mang lại, độ lớn của 1 đơn vị tính năng phần mềm (unit of function) cần đủ nhỏ để kịch bản kiểm thử dễ dàng được xây dựng và đọc hiểu, công sức debug kịch bản kiểm thử khi chạy thất bại cũng giảm thiểu hơn.
Thực tế cho thấy một số sự kết hợp giữa TDD và mô hình Agile khác như Scrum có thể hỗ trợ và tối ưu lợi ích của nhau. Ví dụ, việc chia nhỏ Backlog thành các User Story của Scrum khiến việc xây dựng kịch bản kiểm thử hướng TDD trở nên dễ dàng và thuận tiện. Thêm vào đó, cả Scrum và TDD tương đồng trong việc loại bỏ sự chuyên hóa về vai trò của bộ đôi Developer – Tester. Vì lý do đó, đôi lúc có thể bạn sẽ thấy vừa TDD vừa Scrum được áp dụng trong cùng 1 dự án.
4. Behavior-Driven Development - BDDNhư vậy, trong mô hình TDD nhiệm vụ kiểm thử do developer đảm nhiệm và vai trò chuyên hóa của người tester gần như không còn nữa. Chắc hẳn các bạn sẽ tự hỏi: “Vậy một Acceptance Tester như chúng ta có vai trò gì trong mô hình?”, “Tại sao tôi phải hiểu về TDD khi người ta ko cần tôi trong quy trình đó?”
Quả thực, trong mô hình TDD người Acceptance Tester thực sự đã chết. Tuy nhiên, việc cộng gộp vai trò phát sinh vấn đề quá tải cho người developer. Để làm tốt công việc, xuyên suốt chu trình người developer phải chú ý thêm những vấn đề thuần túy của kiểm thử (test) như: “Cái gì cần test và cái gì không?” “Viết bao nhiêu kịch bản là đủ?” “Làm sao để hiểu là test đó thất bại?” “Bắt đầu test từ đâu?” …
Để giải quyết vần đề phát sinh mà vẫn tận dụng triệt để lợi ích mà TDD mang lại, Dan North phát triển một mô hình mới với tên gọi: Behavior-Driven Development – BDD (hoặc ta có thể hiểu là Acceptance Test-Driven Development – ATDD) [5]. Trong đó, một vai trò mới trong việc thiết kế kiểm thử (Test Design) được đặt ra:

-  Thay vì chờ đợi sản phẩm hoàn thành và kiểm thử, người tester/analyst tham gia vào quá trình xây dựng mã nguồn với vai trò phân tích và xây dựng hệ thống kịch bản kiểm thử dưới góc độ ngôn ngữ tự nhiên dễ hiểu từ các yêu cầu (requirement).

-  Đồng thời, họ giúp đỡ developer trong việc giải thích và đưa ra các phương án xây dựng mã nguồn mang tính thực tiễn với người dùng ngay trước khi bắt tay xây dựng.

-  Người developer liên hệ mật thiết với người tester và xây dựng mã nguồn với những phương án mà tester cung cấp theo mô hình TDD.

-  Kịch bản kiểm thử được phân chia làm 2 lớp: Lớp chấp nhận (feature/acceptance test) và Lớp đơn vị (unit test).

-  Theo đó, kịch bản kiểm thử lớp đơn vị mang thuần tính thiết kế và phục vụ cho việc kiểm thử lớp đơn vị (Unit test) còn kịch bản kiểm thử lớp chấp nhận có thể được tái sử dụng cho quá trình kiểm thử hồi quy về sau (Regression Test)

Từ mô hình trên ta dễ dàng nhìn nhận được sự ưu việt BDD mang lại đặc biệt là trong các dự án phần mềm lớn và phức tạp, khi cả hai khía cạnh phân hóa vai trò và chất lượng phải đi đôi. Ngoài ra, việc chạy kịch bản kiểm thử và xử lý sớm các vấn đề thiết kế ngay trong khâu xây dựng giúp giảm thiểu tối đa chi phí và công sức sửa chữa lỗi.
Trong khi khái niệm BDD mang tính lý thuyết, việc ứng dụng của nó lại đặt nặng sự thực nghiệm. Để phát huy lợi ích về thời gian trong việc xây dựng kịch bản kiểm thử, ngôn ngữ và cách truyền tải là 1 thử thách khi phải đáp ứng khả năng đọc hiểu từ cả 2 khía cạnh: tự nhiên và thiết kế. Bằng sự vay mượn từ ngôn ngữ viết User Story, ngôn ngữ Gherkin được phát triển để phục vụ nhu cầu đó với cấu trúc đơn giản, hướng đối tượng và tương đồng cho mọi kịch bản: Given – When – Then (mình sẽ trình bày rõ hơn về ngôn ngữ này ở các loạt bài khác)

Ví dụ:

Given: Là một sinh viên
When: Tôi đăng ký một khóa học thành công
Then: Tôi phải thấy tên khóa học hiện ra trong danh sách môn học của tôi

5. Agile testing từ góc nhìn một Acceptance Tester
Có thể nhìn nhận rằng cùng với những lợi ích mà tuyên ngôn Agile mang lại, việc nở rộ và chiếm lĩnh của các mô hình hướng Agile như TDD-BDD đang dần dần thay đổi vai trò chuyên hóa của một Acceptance Tester truyền thống trong việc kiểm thử. Công việc kiểm thử dựa trên nguyên tắc đợi sản phẩm phần mềm hoàn tất (một phần hoặc toàn phần) và chạy kiểm thử trên sản phẩm như một người dùng (end-user) trở nên không cần thiết nữa. Thay vào đó, vai trò của người tester có xu hướng chuyển dần sang việc bảo trì chất lượng phần mềm (maintain quality) và hỗ trợ developer trong việc tối ưu sự tiện dụng của sản phẩm ngay từ khâu xây dựng. Trong tương lai, các tester cần có khả năng xây dựng và chạy các bộ kiểm thử mang tính bảo trì chất lượng. Đặc biệt là kiểm thử hồi quy tự động (regression test using automation) và các bộ kiểm thử trọng tải (performance test) – phần việc duy nhất developer không đảm nhiệm.
Tương tự, trong Agile – một bộ phận gia công phần mềm theo hướng truyền thống cũng sẽ dần lụi tàn nếu bản thân dịch vụ gia công không đáp ứng được nhu cầu liên lạc gần gũi giữa tester và developer. Điều này là không dễ khi đa số các dự án gia công luôn có khoảng cách về múi giờ, địa lý và văn hóa giữa offshore tester và đội ngũ developer. Thêm vào đó, trình độ tester cũng là một mối quan tâm lớn khi ở trong BDD tester cần có khả năng đọc mã nguồn để có thể đưa ra các giải pháp cải tiến thiết kế cho developer.
6. Kết luậnTrên đây là những chia sẻ và nhận định chủ quan của mình về TDD-BDD nói riêng và Agile nói chung, những ảnh hưởng của nó dưới góc nhìn một người Acceptance Tester. Hiện tại trên mạng có rất nhiều tài liệu về hai mô hình này với mức độ chi tiết và ứng dụng khác nhau từ nhiều góc độ: thiết kế hệ thống, quản lý và xây dựng quy trình … đủ để phục vụ mục đích nghiên cứu nếu các bạn có nhu cầu. Những nội dung trên là những kiến thức cơ bản nhất do mình lượm lặt và hệ thống hóa trong những năm tháng làm việc với hi vọng có thể giúp các bạn có cách tiếp cận nhanh và dễ hiểu nhất. Mình rất mong có được những phản hồi và đóng góp của các bạn nhằm làm giàu và sửa chữa những kiến thức mình còn khiếm khuyết.
Trích: hoidapit

translate

Hôm nay đọc gì

Lưu trữ

view

view