Làm thế nào bạn có thể TDD cho một lỗi chỉ có thể được kiểm tra sau khi nó đã được sửa?


13

Đây là một ví dụ: Ứng dụng web của tôi chứa các yếu tố có thể kéo được. Khi kéo một phần tử, trình duyệt sẽ tạo ra một "hình ảnh ma". Tôi muốn xóa "hình ảnh ma" khi kéo và tôi viết một bài kiểm tra cho hành vi này.

Vấn đề của tôi là ban đầu tôi không biết làm thế nào để sửa lỗi này và cách duy nhất tôi có thể viết một bài kiểm tra là sau khi tôi đã sửa nó.

Trong một chức năng đơn giản như let sum = (a, b) => a - b, bạn có thể viết một bài kiểm tra tại sao sum(1, 2)không bằng 3trước khi viết bất kỳ mã nào.

Trong trường hợp tôi đang mô tả, tôi không thể kiểm tra, vì tôi không biết xác minh là gì (tôi không biết xác nhận nên là gì).

Một giải pháp cho vấn đề được mô tả là:

let dataTransfer = e.dataTransfer
let canvas = document.createElement('canvas');
canvas.style.opacity = '0';
canvas.style.position = 'absolute';
canvas.style.top = '-1000px';
dataTransfer.effectAllowed = 'none';

document.body.appendChild(canvas);
dataTransfer.setDragImage(canvas, 0, 0);

Tôi không thể biết rằng đây là giải pháp. Tôi thậm chí không thể viết bài kiểm tra sau khi tìm giải pháp trực tuyến, bởi vì cách duy nhất tôi có thể biết nếu nó thực sự hoạt động, là thêm mã này vào cơ sở mã của tôi và xác minh với trình duyệt nếu nó có hiệu quả mong muốn. Bài kiểm tra phải được viết sau mã, đi ngược lại TDD.

Cách tiếp cận TDD cho vấn đề này là gì? Là viết bài kiểm tra trước khi mã bắt buộc hoặc tùy chọn?


2
Làm nghiên cứu của bạn sau đó. Tìm một giải pháp ... sau đó viết bài kiểm tra, sửa chữa và tái cấu trúc của bạn. Các thử nghiệm không nhằm (chỉ) xác minh rằng mã của bạn hoạt động, nhưng để chứng minh trong tương lai giải pháp hoàn chỉnh của bạn. Ban đầu bạn tạo thử nghiệm của mình để thất bại, bạn sẽ thử nghiệm thuộc tính nào? Đó là một cách để bắt đầu.
Juan Carlos Eduardo Romaina Ac

@Kilian Foth: Tôi thấy ý định tốt của bạn bằng cách thay đổi tiêu đề câu hỏi, nhưng phần chỉnh sửa của bạn không hợp lệ trong câu trả lời của tôi. Hơn nữa, tiêu đề mới của bạn đã làm IMHO không phù hợp với cơ thể câu hỏi. Vì vậy, tôi đã thực hiện một rollback, không có hành vi phạm tội.
Doc Brown

Câu trả lời:


26

Khi tôi hiểu đúng về bạn, bạn thậm chí không thể viết một bài kiểm tra tự động đáng tin cậy cho ví dụ "hình ảnh ma" của mình sau khi bạn tìm thấy giải pháp, vì cách duy nhất để xác minh hành vi chính xác là nhìn vào màn hình và kiểm tra xem không có hình ảnh ma nữa không. Điều đó cho tôi ấn tượng tiêu đề ban đầu của bạn hỏi câu hỏi sai. Câu hỏi thực sự nên là

  • Làm thế nào để tự động kiểm tra một hành vi nhất định của giao diện người dùng đồ họa?

Và câu trả lời là - đối với một số loại vấn đề UI, bạn không . Chắc chắn, người ta có thể cố gắng tự động hóa làm cho UI hiển thị vấn đề bằng cách nào đó và cố gắng thực hiện một cái gì đó như so sánh ảnh chụp màn hình, nhưng điều này thường dễ bị lỗi, dễ vỡ và không hiệu quả về chi phí.

Đặc biệt là "lái thử" thiết kế giao diện người dùng hoặc cải tiến giao diện người dùng bằng các bài kiểm tra tự động được viết trước là hoàn toàn không thể. Bạn "lái" thiết kế giao diện người dùng bằng cách cải tiến, hiển thị kết quả cho một người (chính bạn, một số người thử nghiệm hoặc người dùng) và yêu cầu phản hồi.

Vì vậy, chấp nhận thực tế TDD không phải là viên đạn bạc và đối với một số loại vấn đề vẫn là kiểm tra thủ công có ý nghĩa hơn so với kiểm tra tự động. Nếu bạn có một quy trình kiểm tra có hệ thống, có thể với một số người kiểm tra chuyên dụng, điều tốt nhất bạn có thể làm là thêm trường hợp vào kế hoạch kiểm tra của họ.


Trong thử nghiệm UI nói chung là không tầm thường; bạn có thể ghim tức là băm một hình ảnh được tạo, bạn có thể mô phỏng / tự động hóa, bạn có thể ghi lại các macro, bạn có thể sử dụng một giải pháp độc quyền, bạn có thể sử dụng kiểm tra thủ công, tùy thuộc vào tình huống và cách kiểm tra giao diện người dùng tự động cần thiết cho dự án của bạn.
esoterik

1
@esoterik: vâng, và tất cả các kỹ thuật tự động này dễ bị lỗi và dễ vỡ, như tôi đã viết. Cách tiếp cận không dễ vỡ duy nhất tôi biết là thử nghiệm thủ công.
Doc Brown

3
Cảm ơn đã trả lời. Tôi nghĩ bạn đúng, tôi hy vọng sẽ tìm thấy một viên đạn bạc trong TDD. Dường như không có cách nào hiệu quả để kiểm tra những gì tôi muốn kiểm tra - so sánh ảnh chụp màn hình và tất cả những điều trên dường như không cho ROI đủ. So sánh ảnh chụp màn hình nói riêng dường như rất tốn thời gian và, như bạn đã nói, dễ bị lỗi.
maximedupre

1
@maximedupre: tìm thấy quảng cáo này cho một công cụ cố gắng giải quyết vấn đề, tuy nhiên bài báo dường như đồng ý với câu trả lời của tôi nói chung.
Doc Brown

5

Cách tiếp cận TDD cho vấn đề này là gì? Là viết bài kiểm tra trước khi mã bắt buộc hoặc tùy chọn?

Một cách là áp dụng một tương tự của một giải pháp tăng đột biến .

James Shore đã mô tả nó theo cách này:

Chúng tôi thực hiện các thí nghiệm nhỏ, biệt lập khi chúng tôi cần thêm thông tin.

Ý tưởng cơ bản là bạn đặt các công cụ thiết kế xuống trong khi bạn đang tìm hiểu chuyện gì đang xảy ra. Một khi bạn có vòng bi của mình, bạn chọn lại các công cụ thiết kế.

Mẹo: bạn mang kiến thức từ cuộc điều tra của bạn trở lại cơ sở mã sản xuất của bạn, nhưng bạn không mang . Thay vào đó, bạn tạo lại nó trong khi sử dụng các kỹ thuật thiết kế có kỷ luật của bạn.

Ngựa cho các khóa học.

BIÊN TẬP:

Làm thế nào bạn có thể tự động hóa một bài kiểm tra nếu khiếm khuyết chỉ có thể nhìn thấy bằng mắt người?

Tôi muốn đề xuất một cách viết hơi khác: "Làm thế nào bạn có thể tự động kiểm tra nếu tự động hóa bài kiểm tra không hiệu quả về chi phí?"

Câu trả lời, tất nhiên, là "bạn không". Thay vào đó, hãy cố gắng tách việc thực hiện của bạn thành hai phần - một phần lớn trong đó thử nghiệm có hiệu quả về chi phí và một phần nhỏ quá đơn giản để phá vỡ.

Có hai cách để xây dựng một thiết kế phần mềm: Một cách là làm cho nó đơn giản đến mức rõ ràng là không có thiếu sót - CAR Hoare

Vì vậy, khi làm việc với mã của bên thứ ba, chúng ta sẽ có một lớp mã rất mỏng hoạt động như một proxy cho thư viện của bên thứ ba. Trong thử nghiệm, chúng tôi thay thế shell đó bằng "test double", để xác minh giao thức , mà không phải lo lắng rằng nó tạo ra các hiệu ứng mong muốn.

Để kiểm tra tích hợp mã của chúng tôi với mã bên thứ ba thực sự, chúng tôi dựa vào các kỹ thuật khác (xác minh trực quan, gọi hỗ trợ kỹ thuật, lạc quan ....)

Nó có thể hữu ích để giữ một số đồ tạo tác trình diễn xung quanh, để bạn có thể kiểm tra xem các giả định của bạn có còn giữ khi bạn nâng cấp thư viện của bên thứ ba không.


Tôi yêu những gì James Shore nói. Tôi hiện đang theo dõi screencast www.letscodejavascript.com và tôi đang học hỏi rất nhiều. Tôi sẽ đọc các liên kết bạn chỉ cho tôi.
maximedupre

Bạn nói đúng, tôi đọc thêm về TDD và gai. Bạn thực sự cần phải biết mã bạn đang cố kiểm tra trông như thế nào trước khi thử kiểm tra nó. TDD không thể dạy cho bạn bất cứ điều gì bạn chưa biết, nhưng nó có khả năng cho bạn thấy một số điều bạn cần học, diễn giải James Shore. Về lưu ý đó, tôi muốn đề xuất một bước bổ sung trong TDD: Spike, Test, Fail, Pass, Refactor.
maximedupre

0

Chỉ là một góc nhìn khác, thử nghiệm xung quanh UI / GUI có thể được thực hiện tốt hơn một chút đối với thử nghiệm chấp nhận (các thử nghiệm tập trung vào công việc / tính năng công việc).

Đối với web, tôi nghĩ rằng các khung như selenium webdo có khả năng tiến gần đến kiểm tra chính xác, nhưng chi phí để bắt đầu có thể hơi nhiều và đó là một sự thay đổi trong dòng chảy được thấy với TDD so với chỉ kiểm tra đơn vị .

Phần đặc biệt giúp ích cho tình huống của bạn là một cái gì đó được gọi là Mô hình đối tượng trang ( https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html ). Điều này đạt được một ánh xạ rõ ràng của GUI thời gian chạy tới một số mã, bằng cách đặt tên các phương thức / sự kiện / thành viên lớp.

Các đối số chính chống lại điều này sẽ là chi phí chung và rằng chi phí này thường có thể được nhìn thấy ở cuối chu kỳ để phát triển. Chi phí hoạt động mà các bài kiểm tra yêu cầu một số trình bao bọc sẽ xuất hiện để tạo ra công việc trùng lặp.

Tiến về phía trước, nó sẽ phụ thuộc vào chi phí / lợi ích của nhóm và doanh nghiệp, vì vậy đây có thể là một chủ đề có lợi để thảo luận để xác định kỳ vọng và quan điểm.


Tôi thực sự đã thử các bài kiểm tra e2e / chức năng (với weben selenium) trong TDD gần đây, nhưng chi phí chắc chắn là quá lớn như bạn nói. Bạn không thể là một nhà phát triển hiệu quả và làm TDD với các bài kiểm tra e2e. Tôi đã sử dụng POM, nhưng lợi ích duy nhất mà nó mang lại cho tôi là một kiến ​​trúc được cải thiện trong cơ sở mã thử nghiệm của tôi.
maximedupre

Vâng, tôi nghĩ rằng một lựa chọn khả thi hơn mà tôi đã thấy từ các công ty khác nhau cho các nhóm khác nhau sẽ là kết hợp quy trình SQA thủ công hơn, trong đó một thành viên nhóm / thành viên nhóm được chỉ định chỉ kiểm tra thủ công từ UI. Các bài kiểm tra hầu hết có ảnh chụp màn hình và tài liệu từng bước. Ít nhất, một cái gì đó như thế sẽ tạo ra một số bằng chứng về thử nghiệm đối với một ứng dụng.
eparham7861

0

Một hình ảnh ma trông như thế nào? Nếu bạn đã tạo một hình nộm của một màu đã biết, bạn đặt thành phần có thể kéo của mình ở đâu? Sẽ có một màu cụ thể nếu có hình ảnh ma.

Sau đó, thử nghiệm có thể kiểm tra sự vắng mặt của màu sắc của hình ảnh ma.

Thử nghiệm như vậy sẽ là hợp lý bền và có thể làm được.


Có thể làm được - vâng. Bền - phụ thuộc. Chỉ cần thay đổi màu sắc / chủ đề của giao diện người dùng của bạn có thể phá vỡ các thử nghiệm của bạn, điều đó không có vẻ quá bền đối với tôi.
Sean Burton

1
Bạn sẽ không kiểm tra toàn bộ UI của bạn. Bạn sẽ tạo một ui giả cho thành phần kéo-n-drop.
Esben Skov Pedersen

Tôi không chắc làm thế nào để thực hiện những gì bạn đang đề xuất. Một hình ảnh ma trong trường hợp của tôi sẽ là một bản sao bán mờ của phần tử đang được kéo. Hình ảnh ma đang theo dõi con trỏ mọi lúc trong khi kéo và thả đang xảy ra.
maximedupre

Đúng. Bạn sẽ phải tự động kéo. Nó sẽ không phải là một bài kiểm tra đơn vị mà là một bài kiểm tra e2e.
Esben Skov Pedersen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.