Làm thế nào để viết các bài kiểm tra có ý nghĩa cho phần mềm trực quan?


8

Tôi có một phần mềm khá lớn chứa các loại tệp nhất định và trực quan hóa chúng / tạo ra một loạt các nút để thao tác với hình ảnh được vẽ. Tôi cảm thấy như tôi đang tìm thấy các lỗi / đoạn mã không thực sự hoạt động mỗi tuần một lần, nhưng tôi đang vật lộn để hiểu làm thế nào tôi có thể viết bài kiểm tra cho phần mềm này?

Tôi hiểu các bài kiểm tra quan trọng như thế nào đối với các dự án như thư viện và API, bạn chỉ cần viết các bài kiểm tra sử dụng các hàm này.

Nhưng những gì về phần mềm trực quan? Nó dường như đòi hỏi một cách tiếp cận khác do các yếu tố thị giác liên quan.

Tôi có cần phải viết chương trình thử nghiệm hoặc khai thác thử nghiệm để chạy và gọi thủ công mọi thao tác với điều kiện tôi có thể sử dụng trên dữ liệu không?

Tôi nên sử dụng phương pháp nào để bắt đầu viết bài kiểm tra để xác thực rằng tôi đã sửa các lỗi và để thông báo cho tôi nếu mã bị hỏng lần nữa?


Có một câu hỏi trùng lặp liên quan nhưng không liên quan đến khi bạn nên kiểm tra đơn vị. Vì tôi phát hiện ra lỗi, tôi muốn viết các bài kiểm tra để giúp ngăn phần mềm hồi quy lại.

Câu trả lời:


8

Có một vài điều bạn có thể làm để làm cho phần mềm thử nghiệm như vậy dễ dàng hơn. Trước tiên, hãy cố gắng trừu tượng hết mức có thể thành các lớp không trực quan. Điều đó sẽ cho phép bạn chỉ viết các bài kiểm tra đơn vị tiêu chuẩn trên các lớp thấp hơn. Ví dụ: nếu bạn có một nút thực hiện một phép tính nhất định, hãy đảm bảo rằng bạn có cách để thực hiện phép tính đó trong một bài kiểm tra đơn vị bằng một lệnh gọi hàm thông thường.

Gợi ý khác để kiểm tra các chương trình nặng về đồ họa là tạo một số đầu ra mà người kiểm tra có thể dễ dàng xác minh bằng tay. Một ví dụ về minecraft là:

đầu ra thử nghiệm minecraft

Tôi cũng đã làm việc với các dự án có một loạt các thử nghiệm hiển thị một cái gì đó trên màn hình, sau đó nhắc người kiểm tra xác minh thủ công nó phù hợp với mô tả. Điều này đảm bảo bạn không quên các trường hợp kiểm tra sau này.

Kiểm tra thường cực kỳ khó khăn nếu ban đầu bạn không thiết kế với kiểm tra. Chỉ cần làm việc để đưa mã dễ vỡ nhất của bạn vào thử nghiệm đầu tiên. Khi bạn tìm thấy một lỗi, hãy thực hiện một bài kiểm tra sẽ bắt lỗi đó nếu nó xảy ra lần nữa. Điều đó thường nhắc viết các bài kiểm tra liên quan trong khi bạn đang ở đó.


2
+1 và nếu dữ liệu thử nghiệm hiển thị hình ảnh tĩnh, hãy xác minh thủ công kết quả lần đầu tiên sau đó lưu ảnh chụp màn hình để so sánh theo chương trình sau đó
Steven A. Lowe

6

Mọi thứ đều có giao diện. Khi tôi đội chiếc mũ thử nghiệm của mình, tôi sử dụng một thế giới quan cụ thể để viết một bài kiểm tra:

  • Nếu một cái gì đó tồn tại, nó có thể được đo.
  • Nếu nó không thể được đo, nó không thành vấn đề. Nếu nó thành vấn đề, tôi chưa tìm ra cách nào để đo nó cả.
  • Yêu cầu quy định các thuộc tính có thể đo lường được, hoặc chúng là vô dụng.
  • Một hệ thống đáp ứng một yêu cầu khi nó chuyển từ trạng thái không mong đợi sang trạng thái dự kiến ​​được quy định bởi yêu cầu.
  • Một hệ thống bao gồm các thành phần tương tác, có thể là các hệ thống con. Một hệ thống là chính xác khi tất cả các thành phần là chính xác và sự tương tác giữa các thành phần là chính xác.

Trong trường hợp của bạn, hệ thống của bạn có ba phần chính:

  • một số loại dữ liệu hoặc hình ảnh, có thể được khởi tạo từ các tệp
  • một cơ chế hiển thị dữ liệu
  • một cơ chế để sửa đổi dữ liệu

Ngẫu nhiên, điều đó nghe rất giống kiến ​​trúc Model-View-Controller ban đầu đối với tôi. Lý tưởng nhất, ba yếu tố này thể hiện khớp nối lỏng lẻo - nghĩa là, bạn xác định ranh giới rõ ràng giữa chúng với các giao diện được xác định rõ (và do đó có thể kiểm tra tốt).

Một tương tác phức tạp với phần mềm có thể được dịch thành các bước nhỏ có thể được thực hiện theo các yếu tố của hệ thống mà chúng tôi đang thử nghiệm. Ví dụ:

Tôi tải một tập tin với một số dữ liệu. Nó hiển thị một biểu đồ. Khi tôi kéo một thanh trượt trong giao diện người dùng, biểu đồ sẽ trở nên chao đảo.

Điều này dường như dễ dàng để kiểm tra thủ công và khó kiểm tra tự động. Nhưng hãy dịch câu chuyện đó vào hệ thống của chúng tôi:

  • UI cung cấp một cơ chế để mở tệp: Bộ điều khiển là chính xác.
  • Khi tôi mở một tệp, Bộ điều khiển đưa ra một lệnh thích hợp cho Mô hình: Tương tác Mô hình Bộ điều khiển là chính xác.
  • Đưa ra một tệp thử nghiệm, mô hình phân tích cú pháp này vào cấu trúc dữ liệu dự kiến: Mô hình là chính xác.
  • Đưa ra cấu trúc dữ liệu thử nghiệm, Chế độ xem hiển thị đầu ra dự kiến: Chế độ xem là chính xác. Một số cấu trúc dữ liệu thử nghiệm sẽ là đồ thị bình thường, một số khác sẽ là đồ thị lung lay.
  • Mô hình View tương tác là chính xác
  • Giao diện người dùng cung cấp một thanh trượt để làm cho biểu đồ chao đảo: Bộ điều khiển là chính xác.
  • Khi thanh trượt được đặt thành một giá trị cụ thể, Bộ điều khiển sẽ đưa ra lệnh mong đợi cho Mô hình: Tương tác Mô hình Bộ điều khiển là chính xác.
  • Khi nhận được lệnh kiểm tra liên quan đến độ chao đảo, Mô hình sẽ chuyển đổi cấu trúc dữ liệu thử nghiệm thành cấu trúc dữ liệu kết quả dự kiến.

Được nhóm theo thành phần, chúng tôi kết thúc với các thuộc tính sau để kiểm tra:

  • Mô hình:
    • phân tích cú pháp tập tin
    • đáp ứng với lệnh mở tệp
    • cung cấp quyền truy cập vào dữ liệu
    • đáp ứng với lệnh make-wobbly
  • Lượt xem:
    • kết xuất dữ liệu
  • Điều khiển:
    • cung cấp quy trình mở tệp
    • vấn đề mở tệp
    • cung cấp quy trình làm việc lung lay
    • vấn đề lệnh make-wobbly
  • Toàn bộ hệ thống:
    • kết nối giữa các thành phần là chính xác.

Nếu chúng ta không phân tách vấn đề kiểm tra thành các bài kiểm tra nhỏ hơn, việc kiểm tra trở nên thực sự khó khăn và thực sự mong manh. Câu chuyện trên cũng có thể được triển khai như là khi tôi tải một tệp cụ thể và đặt thanh trượt thành một giá trị cụ thể, một hình ảnh cụ thể được hiển thị. Điều này là dễ vỡ vì nó bị hỏng khi bất kỳ yếu tố nào trong hệ thống thay đổi.

  • Nó bị vỡ khi tôi thay đổi các điều khiển cho sự chao đảo (ví dụ: xử lý trên biểu đồ thay vì một thanh trượt trong bảng điều khiển).
  • Nó bị vỡ khi tôi thay đổi định dạng đầu ra (ví dụ: bitmap được hiển thị khác vì tôi đã thay đổi màu mặc định của biểu đồ hoặc vì tôi đã thêm khử răng cưa để làm cho biểu đồ trông mượt mà hơn. Lưu ý rằng trong cả hai trường hợp này).

Các thử nghiệm dạng hạt cũng có lợi thế thực sự lớn khi chúng cho phép tôi phát triển hệ thống mà không sợ phá vỡ bất kỳ tính năng nào. Vì tất cả các hành vi cần thiết được đo bằng một bộ kiểm tra hoàn chỉnh, các bài kiểm tra sẽ thông báo cho tôi nếu có bất cứ điều gì phá vỡ. Vì chúng là dạng hạt, chúng sẽ chỉ cho tôi khu vực có vấn đề. Ví dụ: nếu tôi vô tình thay đổi giao diện của bất kỳ thành phần nào, chỉ có các thử nghiệm của giao diện đó sẽ thất bại và không có thử nghiệm nào khác xảy ra khi sử dụng gián tiếp giao diện đó.

Nếu thử nghiệm được cho là dễ dàng, điều này đòi hỏi một thiết kế phù hợp. Ví dụ, có vấn đề khi tôi kết nối các thành phần cứng trong hệ thống: nếu tôi muốn kiểm tra sự tương tác của một thành phần với các thành phần khác trong hệ thống, tôi cần thay thế các thành phần khác đó bằng các sơ khai kiểm tra để tôi đăng nhập, xác minh, và biên đạo mà tương tác. Nói cách khác, tôi cần một số cơ chế tiêm phụ thuộc, và nên tránh phụ thuộc tĩnh. Khi kiểm tra giao diện người dùng, sẽ rất hữu ích khi giao diện người dùng này có thể viết được.


Tất nhiên, hầu hết đó chỉ là ảo mộng về một thế giới lý tưởng, nơi mọi thứ đều tách rời và dễ dàng kiểm chứng và bay kỳ lân lan truyền tình yêu và hòa bình ;-) Trong khi mọi thứ về cơ bản đều có thể kiểm chứng, thì thường rất khó để làm điều đó, và bạn tốt hơn sử dụng thời gian của bạn. Tuy nhiên, các hệ thống có thể được thiết kế để kiểm tra và thông thường, ngay cả các hệ thống kiểm tra không xác định có các API hoặc hợp đồng nội bộ có thể được kiểm tra (nếu không, tôi cá là kiến ​​trúc của bạn là rác rưởi và bạn đã viết một quả bóng lớn). Theo kinh nghiệm của tôi, ngay cả một lượng nhỏ thử nghiệm (tự động) cũng làm tăng đáng kể chất lượng.


2

Bắt đầu với một tập tin đã biết tạo ra một hình ảnh dự kiến. Kiểm tra từng pixel. Mỗi cái nên có một giá trị mong đợi cho một tệp thử nghiệm thủ công đã biết. Bạn nên có một hình ảnh đầu ra dự kiến ​​để so sánh nó với. Bất cứ điều gì "tắt" đều biểu thị một lỗi trong mã của bạn.

Mở rộng tệp thử nghiệm của bạn để hình ảnh đầu ra thay đổi và đạt mọi tính năng của phần mềm.

Kịch bản sẽ có ích cho loại thử nghiệm hộp đen đó. Một tập lệnh đơn giản thực thi bản dựng phần mềm mới nhất của bạn cho đầu vào đã biết và đầu ra dự kiến.

Mặt khác, Kiểm thử đơn vị phải là kiểm thử hộp trắng trong đó bạn lấy phần mềm nhỏ nhất có thể, thường là một chức năng hoặc bất cứ thứ gì, và xem liệu nó có hoạt động như bạn mong đợi không. Bạn có thể thấy màu pixel mà nó trả về, hoặc bất cứ thứ gì. Trong trường hợp này, mã của bạn hoạt động giống như một thư viện, với các API cho tất cả các phần khác trong mã của bạn.

Nếu tất cả được nhét vào một tệp .c với tất cả các chức năng được đưa vào main(), thì bạn đã gặp vấn đề lớn hơn rồi, làm thế nào để kiểm tra.

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.