TDD là một kỹ thuật thiết kế với một hiệu ứng phụ là việc đảm bảo toàn bộ mã nguồn của bạn được thực hiện kiểm thử mức đơn vị. Tuy nhiên, có những điều còn quan trọng hơn cả việc thực hiện kiểm thử. Bạn sẽ vẫn cần xem xét các kỹ thuật kiểm thử khác như kiểm thử chấp nhận sản phẩm (acceptance test) hay kiểm thử dò hỏi (investigative test) theo kiểu Agile. Bạn có thể thực hiện nhiều những kiểu kiểm thử này trong dự án nếu như bạn chọn làm điều đó (và bạn nên làm).
Trang 1LOGO Các vấn đề hiện đại của Công nghệ phần mềm
Trang 3 Traditional development cycle
Test-driven development cycle
Test-driven Development 3
Trang 4Test-driven Development
Định nghĩa
TDD là phương pháp tiếp cận cải tiến phát triển PM dựa trên sự lặp lại
của một chu kỳ phát triển:
Viết một automated test case xác định một cải thiện mong muốn hoặc một
chức năng mới.
Tạo ra một lượng chỉ vừa đủ code để vượt qua test case đó.
Cấu trúc lại mã mới với các tiêu chuẩn chấp nhận được.
4
Trang 5Test first Development
Test first Development
Refactoring
Test-driven Development
Test-driven Development 5
Trang 6Phần mềm nên phát triển theo hướng TDD?
TDD và cách kiểm thử truyền thống
Test-driven Development 6
Một mẫu kiểm thử thành công sẽ tìm ra một
hoặc nhiều lỗi.
Hệ thống càng có nhiều rủi ro lớn càng cần
phải có nhiều mẫu kiểm thử được thực hiện.
Khi một mẫu kiểm thử thất bại bạn biết rằng bạn cần phải giải quyết một số vấn đề.
Đạt được 100% khi kiểm thử độ phủ mã nguồn (coverage test) - mọi dòng mã đều được kiểm thử.
Trang 7Phần mềm nên phát triển theo hướng TDD?
TDD là một kỹ thuật đặc tả, đem lại kết quả trong việc kiểm thử mã nguồn tốt
hơn đáng kể so với các kỹ thuật truyền thống.
TDD tăng niềm tin hệ thống của bạn đáp ứng được các yêu cầu, hệ thống của
bạn đang hoạt động và có thể tiếp tục.
Một lợi thế đáng kể của TDD là nó cho phép bạn thực hiện các bước nhỏ khi
viết phần mềm.
Test-driven Development 7
Trang 8 Nhiều người cho rằng các kỹ thuật Agile hoạt động rất ổn với những dự án nhỏ, cần một số ít người trong
một vài tháng, nhưng chúng không hoạt động đối với những dự án thực sự lớn hơn Tuy nhiên, điều đó
không hoàn toàn đúng
Ví dụ: một hệ thống Smalltalk
– TDD
• 4 năm, 40 man-year
• 250,000 function code lines; 25000 test code lines
• 4000 test case: ~ 20 min
– Bộ kiểm thử đầy đủ: ~ vài ngày
TDD vẫn hoạt động tốt với những dự án có kích thước lớn.
Test-driven Development 8
Phần mềm nên phát triển theo hướng TDD?
Trang 9Chu trình phát triển
Test-driven Development 9
Trang 10Add a test
Mỗi tính năng mới bắt đầu bằng
cách viết một test
Test này chắc chắn phải thất bại vì
nó được viết trước khi tính năng
được thực hiện
Để viết một test, phải hiểu rõ đặc
tả yêu cầu của tính năng này.
Test-driven Development 10
Trang 11Run all tests and see if the new one
Trang 12Write some code
Viết một số mã để pass Mã mới
được viết trong giai đoạn này là
không hoàn hảo Điều đó là chấp
nhận được vì các bước sau sẽ cải
thiện nó
Tại thời điểm này, mục đích duy
nhất của các mã được viết là phải
vượt qua các test.
Test-driven Development 12
Trang 13Run tests
Nếu tất cả các test cases đều
pass, lập trình viên có thể tự tin
rằng code đã đáp ứng được tất
cả các yêu cầu
Test-driven Development 13
Trang 14Refactor code
Quá trình làm thay đổi code hiện
có mà không cần thay đổi hành vi
bên ngoài của nó
Trang 15Bắt đầu với một test mới, chu kỳ
sau đó được lặp đi lặp lại để hoàn
thiện các chức năng
Test-driven Development 15
Trang 16 Hạn chế các lỗi bên trong
Giảm bớt sự thay đổi
Tài liệu cho nhà phát triển
Lập trình viên được làm chủ
16
Trang 17Ưu điểm
Chất lượng
Chất lượng trên nhiều khía cạnh : thiết kế hướng dẫn, định hướng
Tiêu chí : gán chất lượng với số lỗi tìm ra sau khi sử dụng phần mềm, chi phí bảo trì.
Tất cả các chức năng được cài đặt đều có giá trị
Kỹ năng test : hỗ trợ giao diện cho các modules, class, những gì bạn có và được đảm
bảo bởi QA
Giảm thời gian cho fix lỗi : fix các lỗi tốn hơn 40 lần so với việc viết code mới => test
làm mịn + liên tục chạy test
Test-driven Development 17
Trang 18Viết test đầu tiên
Cài đặt code theo các testcase Xác định chức năng
18
Trang 19Ưu điểm
Xác định đúng chức năng
Nhu cầu trao đổi để xác định chức năng là bắt buộc định hình ý tưởng thiết kế
Các lập trình viên được chủ động
Không ai đảm bảo một hệ thống có nhiều nguy cơ “We don’t touch that, it might break!”
Các lập trình viên có thể làm mọi thứ trên code của mình miễn là code đấy test pass
Với một test hoàn thành : nếu
• Test fails, bạn biết bạn đã phá vỡ cái gì đó
• Test pass, không cần phải làm gì nữa
Test-driven Development 19
Trang 20Ưu điểm
Tài liệu cho các nhà phát triển:
Các test mô tả sự hiểu biết của bạn về chức năng đó của dự án
Việc thêm một vài comment trước mỗi test là bạn đã có một tài liệu hướng dẫn cho các nhà phát triển khác
Giảm bớt sự thay đổi
Thêm chức năng
Yêu cầu mới
Cấu trúc lại
Test-driven Development 20
Trang 21TDD cho các công nghệ phát triển
Với các thành phần web
Java Servlets
• Hai đối tượng HttpServletRequest đại diện request HTTP đóng gói các thông tin cần thiết và HttpServletResponse là cổng tạo ra phản ứng cho phía client.
• Làm thế nào test với hoạt động 2 đối tượng này ?
=> Tạo các request và response giả mạo
• Muốn test Servlet trước cần xác minh rằng nó thực sự tạo các response dự kiến.
• Chúng ta phải cung cấp các trường hợp mà HttpServletRequest và HttpServletResponse có thể gọi với một cặp test
có sẵn của bên thứ ba
Test-driven Development 21
Trang 22TDD cho các công nghệ phát triển
MockHttpServletRequest request = create fake request
new MockHttpServletRequest("GET", "/login");
Trang 23TDD cho các công nghệ phát triển
Spring controllers
Framework Spring ứng với phần C trong mô hình MVC
Đối với một Spring Controller không chịu trách nhiệm response cho request Thay vào đó, chúng chỉ
ra những gì mà framework có thể trả lại một đối tượng ModelAndView
Test-driven Development 23
Trang 24TDD cho các công nghệ phát triển
Spring controllers
Mô phỏng
public class SampleController implements Controller {
protected ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return new ModelAndView("viewname");
}
}
Các Sample sẽ ánh xạ để xử lý Các URL cụ thể
Đối tượng request đến cổng để lấy tất cả dữliệu cần để làm bất cứ điều gì SampleController cần
để làm, và đối tượng ModelAndView trả lại nói với Spring MVC cái nhằm trả lại các response
Test-driven Development 24
Trang 25TDD cho các công nghệ phát triển
Spring controllers
Chúng ta bắt đầu viết test thứ nhất với ví dụ đăng nhập tương tự như trên với Spring MVC
public class TestLoginController {
Controller c = new LoginController(); invock
ModelAndView v = c.handleRequest(request, response);
assertEquals("wrongpassword", v.getViewName()); wrongpass
}
}
Test-driven Development 25
Trang 26TDD cho các công nghệ phát triển
TDD với truy cập dữ liệu
Phương pháp truyền thống test truy cập dữ liệu một cách thủ công chậm và dễ bị lỗi
Chúng ta có những lợi thế tương đối và bất lợii trong việc áp dụng TDD với hội nhập và chiến lược khác nhau cho quan lý dữ liệu
Trang 27Hướng phát triển, TDD cho các công nghệ phát triển
TDD với Swing
Internal plumbing and utilities: mặc dù giao diện người dùng chỉ là cách trình bày và bố trí các hình ảnh , điều đó không có nghĩa là không có cách phần code thực tế là không giống vớinhững gì chúng ta
có thể viết trong khi phát triển hệ thống
Redering and layout:
• muốn đặt các layout đúng để xác nhận như là một phần của việc test
• Đôi khi cần test cho việc bố tri sthô những gì chúng ta cần bố trí
• “Button A nên ở trên button B khi bảng C đưa ra” hoặc ngược lại
Interaction: loại tương tác này không phải là có thể test một cách tâm thường
Chúng ta có thể kiểm tra sự tương tác mong muôn dễ dàng miễnlà chugns ta biết Swing
Test-driven Development 27
Trang 28Gắn liền với thiết kế
28
Nhược điểm
Trang 29 Đối với các trường hợp đơn giản bạn mất khoảng 20% của thời gian cài đặt , nhưng vơi các dự
án phức tạp thì nó lớn hơn
Trong các bài toán phức tạp khó tính các testcase, trong những trường hợp đó có thể test tự động song song với thiết kế chứ không thể test đơn vị đơn giản
Nếu một số không thiết kế rõ ràng từ đầu cho đến khi kết thúc
Với cấu trúc dữ liệu và kiểm thử hộp đen việc kiểm thử đơn vị là hoàn hảo nhưng các thuật toán
có hướng thay đổi, tinh chỉn lại cần một thời gian lớn
Test-driven Development 29
Trang 30Nhược điểm
Liên quan chặt chẽ đến agile:
Trao đổi với khách hàng liên tục về những gì bạn đề xuất thực hiện
Tất cả nằm trong tay nhà phát triển nên TDD chỉ tốt khi mà việc ghi chép cho tài liệu test phải rõ ràng
và ngược lại
Tài liệu không phải là một lời thiệu trong mã , mà là văn bản chính thức tồn tại bên ngoài ứng dụng
Test-driven Development 30
Trang 31VI CÁC KHUNG KIỂM THỬ
Ý nghĩa của các khung kiểm thử với TDD?
Tìm hiểu về khung kiểm thử?
Khung kiểm thử Python (Unittest)
Test-driven Development 31
Trang 32• Các kết quả trả về mong muốn
• Các lỗi ngoại lệ mong muốn
Test-driven Development 32
Trang 33Tìm hiểu về Unittest(UT)
3 Đặc điểm của một UT
Đóng vai trò là người sử dụng đầu tiên của hệ thống
Chỉ có giá trị khi chúng có thể phát hiện các vấn đề tiềm ẩn hoặc lỗi kỹ thuật của chương trình
Test-driven Development 33
Trang 34Tìm hiểu về Unittest(UT)
4 Vòng đời của một UT
Test-driven Development 34
Trạng thái tạm ngừng thực hiện, nhằm mục đích phân tích và sửa lỗi của phần mềm
Sau khi đã phát hiện ra lỗi, sửa lỗi thành công thì một
UT đã được vượt qua và hoàn thành xong nhiệm vụ của mình
Trạng thái phát hiện lỗi
của chương trình khi được
thực thi bởi UT
PASSIGNORE
FAIL
Trang 35Tìm hiểu về Unittest(UT)
5 Thiết kế UT
Thiết lập các điều kiện cần thiết: khởi tạo các đối tượng, xác định tài nguyên cần thiết, xây dựng các dữ liệu giả
Triệu gọi các phương thức cần kiểm tra
Kiểm tra sự hoạt động đúng đắn của các phương thức
Dọn dẹp tài nguyên sau khi kết thúc kiểm tra
Test-driven Development 35
Trang 36Tìm hiểu về Unittest(UT)
6 Ứng dụng của UT
Kiểm tra mọi đơn vị nhỏ nhất là các thuộc tính, sự kiện, thủ tục và hàm
Kiểm tra các trạng thái và ràng buộc của đối tượng ở các mức sâu hơn mà thông thường chúng ta không thể truy cập được
Kiểm tra các quy trình (process) và mở rộng hơn là các khung làm việc(workflow - tập hợp của nhiều quy trình)
Test-driven Development 36
Trang 37Tìm hiểu về Unittest(UT)
7 Chiến lược viết mã hiệu quả với UT
Phân tích các tình huống có thể xảy ra với mã
Mọi UT phải bắt đầu với trạng thái “Fail” và kết thúc bằng trạng thái “Pass”
Mỗi khi viết một đoạn mã quan trọng, hãy viết các UT tương ứng cho đến khi bạn không thể nghĩ thêm tình huống nào nữa
Sớm nhận biết các đoạn mã không ổn định và có nguy cơ gây lỗi cao, viết UT tương ứng để khống chế
Test-driven Development 37
Trang 38KHUNG KIỂM THỬ PYUNIT
Test-driven Development 38
Trang 39KHUNG KIỂM THỬ PYUNIT
2 Cấu trúc đơn giản của một testCase
Test-driven Development 39
Trang 40 Bài toán:
Input: Giá trị lần lượt của 3 cạnh một tam giác
Output: Kiểm tra đầu vào này có thỏa mãn điều kiện là tam giác? Nếu có, thuộc loại
tam giác nào?
Hướng giải quyết?
Test-driven Development 40
Trang 41LOGO Các vấn đề hiện đại của Công nghệ phần mềm
Nhóm 8
Thank You !
41