Cách cấu trúc kiểm tra đơn vị cho ứng dụng GUI bằng C # và NUnit


16

Tôi đã được yêu cầu thực hiện một dự án phụ nhỏ để cung cấp một ứng dụng đơn giản cho một trong những khách hàng của chúng tôi. Thông thường tôi sẽ làm việc với mã back-end nơi tôi có tất cả các nhu cầu thử nghiệm của mình và tôi chưa có niềm vui mơ hồ khi viết thử nghiệm cho GUI, vì vậy tôi không rõ nên cài đặt như thế nào mã kiểm tra và các công cụ cho một EXE.

Bản năng đầu tiên của tôi chỉ đơn giản là bao gồm các thử nghiệm với mã ứng dụng, tuy nhiên điều đó sẽ yêu cầu cung cấp một số phụ thuộc cụ thể cho thử nghiệm, mà tôi đã được hướng dẫn cụ thể không giao hàng cho khách hàng. Tôi cũng không thể vắt kiệt tiền mặt cho một công cụ kiểm tra được xây dựng có mục đích, vì vậy tôi cần sử dụng các công cụ tôi có trong tay ( StoryQ , RhinoMocksNUnit), thực sự cần quá đủ để kiểm tra hành vi của một ứng dụng GUI đơn giản. Theo như tôi có thể thấy, điều này khiến tôi cố gắng đạt được sự cân bằng tốt giữa việc giữ cho thiết kế thực sự đơn giản, hoặc cố tình quá kỹ thuật vì lợi ích của các thử nghiệm. Có vẻ như tôi đang xây dựng ứng dụng với logic nghiệp vụ trong một thư viện riêng và thử nghiệm với thư viện như tôi thường làm hoặc tìm một số cơ chế khác để cho phép tôi thực thi mà không cần phá vỡ các mô-đun bổ sung mà thiết kế ứng dụng không thật sự cần.

Chỉnh sửa:
Xin lưu ý rằng câu hỏi này là về cách cấu trúc mối quan hệ giữa NUnit và tệp thực thi của tôi - trái ngược với DLL - chứ không phải về cách tách biệt trình bày và logic kinh doanh.
/Biên tập

Vì vậy, câu hỏi của tôi là:

  1. Có phương pháp cụ thể / được đề xuất nào để định cấu hình ứng dụng GUI đơn giản với các bài kiểm tra đơn vị để cho phép tôi kiểm tra đầy đủ trạng thái và hành vi, sử dụng các công cụ tôi có trong tay và không cần dùng đến kỹ thuật quá mức không?
  2. Tôi đã bỏ lỡ điều gì đó cơ bản về cách NUnit nên được gọi / cấu hình khi kiểm tra EXE (trái ngược với DLL) chưa?
  3. Bạn có thể cung cấp hoặc chỉ cho tôi theo hướng các ví dụ về cách đạt được tất cả những điều này?

Tôi nhận ra rằng có thể có nhiều hơn một cách để làm điều này vì vậy tôi đang tìm kiếm các hướng dẫn thực hiện cụ thể dựa trên kinh nghiệm của bạn.


NUnit không được thiết kế để kiểm tra GUI trực tiếp. Bạn cần tách lớp trình bày của bạn (tức là chế độ xem) khỏi dữ liệu và logic nghiệp vụ (tức là mô hình) để bạn có thể kiểm tra những gì đi vào chế độ xem của mình mà không cần sử dụng chế độ xem.
Bernard

1
@Bernard Câu hỏi này không phải là về việc xếp lớp GUI để kiểm tra. Tôi tự nhiên lớp tất cả các ứng dụng của mình - ngay cả những ứng dụng tầm thường - vì vậy đó thực sự không phải là vấn đề đối với tôi. Tôi đã chỉnh sửa câu hỏi cho phù hợp và tôi hy vọng rằng nó sẽ xóa mọi hiểu lầm. :)
S.Robins

1
Không có gì phức tạp khủng khiếp trong công cụ kiểm tra đơn vị trong EXE. Chỉ cần có DLL thử nghiệm của bạn tham chiếu tệp EXE của bạn, và bạn tốt để đi.
tên

Câu trả lời:


3

Tôi đã đề cập đến một trong những bình luận của mình cho câu trả lời của simoraman rằng tôi đã nghĩ ra một vài cách để làm điều này. Một trong những lựa chọn của tôi tương tự như gợi ý trong câu trả lời của Jalayn để tạo một dự án trùng lặp và tạo một DLL, trong khi ý tưởng khác của tôi là chỉ cần liên kết đến các tệp trong dự án nơi có mã tôi muốn kiểm tra. Mặc dù cả hai tùy chọn có thể được thực hiện để làm việc, nhưng chúng ít hơn lý tưởng.

Trong trường hợp thứ hai, tôi sẽ có một mớ hỗn độn các đơn vị phụ thuộc để quản lý trừ khi tôi thực sự có thể trêu chọc kiến ​​trúc để giảm thiểu sự phụ thuộc. Điều này tốt cho các dự án nhỏ hơn, nhưng những dự án lớn hơn có thể dễ dàng trở thành một mớ hỗn độn thực sự để quản lý. Tuy nhiên, sự phản kháng lớn nhất của tôi đối với lựa chọn này là sự không phù hợp của nó. Chắc chắn tôi có thểlàm cho nó hoạt động, nhưng để làm như vậy tôi thực sự cần phải phá vỡ đóng gói để kiểm tra các phần bên trong của một tổ hợp trực tiếp thông qua nguồn, thay vì kiểm tra thông qua các giao diện công cộng, mà trong tâm trí tôi là một điều không nên. Tương tự như vậy, có một tệp dự án bổ sung có nghĩa là nhân đôi nỗ lực trong hai dự án cùng một lúc hoặc tìm cách tự động thêm cài đặt tệp dự án vào hai tệp hoặc nhớ sao chép và đổi tên trường dự án mỗi lần tôi xây dựng. Điều này có thể được tự động hóa trên máy chủ xây dựng, nhưng sẽ là một nỗi đau để quản lý trong IDE. Một lần nữa, nó có thể hoạt động, nhưng đó là một loại bùn tốt nhất, và phiền toái tồi tệ hơn nếu bạn làm sai.

Cách tốt nhất có vẻ là làm như whatsisname đã bình luận cho câu hỏi của tôi và chỉ đơn giản là đưa EXE làm tài liệu tham khảo trong dự án thử nghiệm. Nó chỉ ra rằng một EXE được đối xử hiệu quả giống như một DLL trong trường hợp này và tôi có thể truy cập tất cả các lớp được xếp lớp độc đáo của mình để kiểm tra bất cứ thứ gì trôi nổi trên thuyền của tôi.


2

Tôi nghĩ vậy:

  • Mã kiểm tra doanh nghiệp của bạn phải nằm trong một dự án riêng, kiểm tra thư viện mã doanh nghiệp của bạn.
  • Mã kiểm tra GUI của bạn phải nằm trong một dự án riêng, kiểm tra thư viện GUI của bạn. Bây giờ, làm thế nào để xây dựng thư viện GUI thay vì thực thi, tôi cố gắng trả lời điều đó sau.
  • Nếu bạn có my.namespace.biz.MyClass, lớp kiểm tra của bạn phải là my.namespace.biz.MyClassTest (hoặc MyClassTestCase).
  • Nếu bạn muốn kiểm tra mã được tìm thấy trong mục tiêu thực thi của mình, thì bạn nên có một thiết lập xây dựng EXE và một thiết lập khác xây dựng thư viện (DLL), đó là thiết lập mà bạn sẽ khởi chạy thử nghiệm của mình.

Đây là những quy tắc mà tôi muốn tuân theo, cho dù đó là Java hay C # (ngoại trừ không có vấn đề EXE với Java tất nhiên :-))

Đối với cách định cấu hình môi trường kiểm tra của bạn, đối với tôi, có ít nhất hai lựa chọn sau:

Sử dụng MSBuild

Tạo một bản sao của tệp .proj của bạn (giả sử myproject-as-dll.proj ). Thay đổi OutputTypetệp trong bản sao từ " EXE" thành " Library". Sử dụng lệnh MSBuild, giờ đây bạn có thể tạo thư viện mà bạn có thể đặt làm tham chiếu vào dự án của mình có chứa các trường hợp thử nghiệm NUnit.

Nó dường như là có thể đối với tôi, nhưng tôi chưa bao giờ sử dụng nó một cách trung thực, vì vậy tôi không chắc chắn. Ngoài ra, bạn có thể không có MSBuild trên máy chủ thử nghiệm tích hợp của mình và tôi không biết liệu nó có thể được tách ra khỏi Visual Studio không ...

Sử dụng NAnt

Nếu bạn không quen thuộc với NAnt, bạn sẽ phải tìm hiểu cách cấu hình các bản dựng dự án của bạn với nó. Có thể kiểm tra cái này , nó hơi cũ nhưng tác giả đã nhận xét các tệp NAnt và Nếu thấy nó tự giải thích. ( Chỉnh sửa: kiểm tra tệp của anh ấy chi tiết hơn, tôi thấy tệp cấu hình của anh ấy có thể tái sử dụng rất nhiều ). Anh ta cũng làm nhiều hơn là chỉ xây dựng, vì anh ta thực hiện các trường hợp thử nghiệm và khởi chạy các công cụ bao phủ mã. Bây giờ, tôi thừa nhận tôi chưa bao giờ sử dụng NAnt, trái với đối tác Java và cha "Ant" mà tôi đã sử dụng rất nhiều nhưng tôi thấy nó hoàn toàn giống nhau và tôi không nghĩ nó khó học.

Với công cụ đó, bạn có thể đưa ra một cấu hình cho phép bạn:

  • xây dựng tất cả các dự án của bạn (logic nghiệp vụ, GUI, v.v.) vào các thư viện riêng
  • xây dựng dự án thử nghiệm của bạn
  • khởi chạy các bài kiểm tra (phần cụ thể đó được thực hiện với tác vụ NUnit2 ).
  • kiểm tra phạm vi bảo hiểm mã của bạn với nhiệm vụ NCover .

Với một chút mã hơn, bạn thậm chí có thể:

  • thực hiện triển khai hàng đêm trong máy chủ tích hợp của bạn
  • nếu NAnt có sẵn trong máy chủ tích hợp của bạn, hãy khởi chạy các thử nghiệm tích hợp hàng đêm với sự trợ giúp của các tác vụ theo lịch trình

Tất cả được thực hiện mà không thay đổi bất cứ điều gì trong các tập tin Visual Studio của bạn. Và, thực sự, nó không giống như quá kỹ thuật đối với tôi, nó chỉ là một tệp. Bạn có thể mất một, có thể hai ngày để làm cho tất cả hoạt động nhưng theo ý kiến ​​của tôi, bạn sẽ có một thiết lập tốt.

Cuối cùng, tôi sẽ cung cấp cho khách hàng tất cả những gì cần thiết để xây dựng, thử nghiệm và chạy các dự án. Tôi có xu hướng nghĩ rằng nó thể hiện sự chuyên nghiệp của bạn và thực tế là bạn viết mã với chất lượng trong tâm trí của bạn (điều này đối với tôi bạn làm vì bạn đang tìm kiếm giải pháp thanh lịch)


0

Chỉ vì dự án nhỏ (ban đầu) không có nghĩa là kiến ​​trúc phù hợp là quá kỹ thuật. Việc bạn muốn viết các bài kiểm tra cho biết rằng dự án của bạn không phải là một bản hack hoàn toàn tầm thường.

Bạn đã không đề cập đến GUI-Framework nào bạn đang sử dụng. WPF MVVM (Model-View-ViewModel) là tốt và cho phép bạn viết các bài kiểm tra cho tất cả logic khá dễ dàng. Với WinForms, tôi đã nghe thấy những điều hay về MVP (Model-View-Presenter)


Tôi viết bài kiểm tra cho tất cả các mã mà tôi viết. Ngay cả những thứ mà bạn có thể tìm thấy tầm thường. Lần duy nhất tôi không viết bài kiểm tra là khi tôi tăng đột biến. Trong trường hợp này, tôi đang chuyển một tiện ích tắt cho khách hàng, vì vậy việc thử nghiệm không chỉ là một thứ xa xỉ, đó là một yêu cầu để đáp ứng các tiêu chuẩn chất lượng của chúng tôi. Về mặt "kỹ thuật quá mức", đây không phải là sự lựa chọn giữa kiến ​​trúc tốt hay xấu, mà là tránh việc phải áp đặt thêm lớp không cần thiết trong trường hợp này vì ứng dụng là mục đích duy nhất với vòng đời tương đối ngắn.
S.Robins

Đối với sự lựa chọn của gui-framework có liên quan, tôi không thấy điều này sẽ ảnh hưởng đến cách mà môi trường thử nghiệm được thiết lập. Tôi đang tìm kiếm CÁCH cụ thể để thực hiện các bài kiểm tra đơn vị cho lớp GUI bằng các công cụ tôi có sẵn. Câu trả lời đặc biệt này không thực sự cho tôi biết bất cứ điều gì về điều đó.
S.Robins

Simoraman - Nếu bạn lấy đi đoạn đầu tiên khá phán xét, điều này sẽ hướng tới một câu trả lời. Khắc phục điều đó và tôi sẽ xóa -1 của tôi. @ S.Robins lưu ý rằng đoạn thứ hai liên quan - mặc dù không phải là một câu trả lời đầy đủ, nó sẽ giúp. Nếu lớp GUI của bạn mỏng, có cấu trúc tốt và rõ ràng và tất cả logic nghiệp vụ được kiểm tra bằng các thử nghiệm đơn vị ở cấp Mô hình, thì có thể bạn không cần phải trải qua thêm rắc rối khi kiểm tra UI một cách rõ ràng.
Đánh dấu gian hàng

1
@MarkBooth Layering không thực sự là một vấn đề. Như simiraman đề cập tôi có thể MVP, MVVM hoặc tôi có thể xây dựng một cái gì đó thậm chí còn mỏng hơn. Tuy nhiên tôi có một số yếu tố cụ thể về GUI sẽ yêu cầu thử nghiệm rõ ràng, đó là lý do tại sao tôi quyết định viết nó thành một câu hỏi. Tôi có một vài ý tưởng, và nếu tệ hơn đến tồi tệ hơn tôi biết rằng cuối cùng tôi sẽ có thể giải quyết vấn đề và tự mình viết ra một câu trả lời. Tuy nhiên tôi đã muốn mở nó ra cho cộng đồng vì tôi nghĩ nó sẽ tạo ra một câu hỏi hay cho Lập trình viên. ;-)
S.Robins

0

Hãy xem câu trả lời của tôi về câu hỏi này: Làm cách nào để thiết lập MVP cho giải pháp Winforms?

Tôi thực sự đã viết một ứng dụng mẫu cho thấy cách tôi lớp và cách tôi kiểm tra, GUI của tôi.

đọc bản chỉnh sửa của bạn: sử dụng một trình chạy thử nghiệm tích hợp với môi trường phát triển của bạn. Tôi sử dụng ReSharper.


Cảm ơn đề xuất ReSharper. Đây là một công cụ mà tôi sử dụng khi phát triển. Thật không may, nó sẽ không giúp ích khi thực hiện các thử nghiệm trên máy chủ xây dựng tích hợp. Nó cũng không cho tôi biết cách định cấu hình các bài kiểm tra Nunit để truy cập mã trong exe khi kiểm tra.
S.Robins

1
Không chính thức, nó làm. Exe chỉ là khung nhìn, tải trình dẫn, mô hình và chế độ xem ra khỏi thư viện lớp như là một phần của khởi động ứng dụng. Ít nhất trong giải pháp của tôi, chế độ xem đủ ngu ngốc để chúng tôi không kiểm tra nó bằng các thử nghiệm tự động và chỉ cần thực hiện các thử nghiệm chấp nhận để đảm bảo mọi thứ được viết đúng và các nút là nơi chúng nên ở. NUnit-tests a dll rất dễ làm.
Bryan Boettcher

0

Tôi đã viết Nunit WinForms vài năm trước (tôi đoán là 6 năm). Một điều mà tôi nhớ cụ thể là mặc dù là trường hợp thử nghiệm đơn vị, nhưng nó cũng hoạt động như trường hợp thử nghiệm từ đầu đến cuối. Đôi khi không có nhiều thứ để kiểm tra ở mặt trước (một hình thức đơn giản). Vì vậy, mặc dù bạn đang cố kiểm tra một hộp thông báo bật lên trên một nút bấm, bạn vô tình thử nghiệm nhiều phương thức khác từ các lớp khác. Có một số điều mà bạn không thể tự động hóa là tốt. Giao diện, cảm nhận và khả năng sử dụng không thể được tự động bằng cách sử dụng thử nghiệm đơn vị tự động. Bạn sẽ phải chạy một số bài kiểm tra thủ công trước khi phát hành.


Nếu khách hàng của bạn chỉ định một màn hình sẽ nhìn theo một cách nhất định hoặc nên thay đổi theo một cách nhất định, thì bạn sẽ có thể kiểm tra những thứ này. Nắm bắt các thông số kỹ thuật như các bài kiểm tra là trái tim của phương pháp BDD và tôi chưa bao giờ tìm thấy một tình huống mà bạn không thể - mặc dù sáng tạo - tìm một phương tiện để tự động hóa một bài kiểm tra. Câu hỏi thực sự là liệu thử nghiệm sẽ có giá trị hay không, liệu ứng dụng có đủ yếu tố để cho phép bạn tự động hóa tất cả các thử nghiệm ở nơi đầu tiên hay không và liệu các thử nghiệm có hiệu quả về chi phí hay không. Mặc dù vậy, tôi đồng ý rằng đôi khi họ không như vậy.
S.Robins
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.