Làm cách nào để thiết kế phần mềm của trò chơi sao cho dễ kiểm tra đơn vị?


25

Có thực tế không khi sử dụng một khung thử nghiệm như JUnit trong tình huống phát triển trò chơi? Những loại cân nhắc thiết kế nào bạn có thể làm theo để làm cho trò chơi của bạn dễ kiểm tra hơn? Những phần nào của trò chơi có thể / nên được thử nghiệm và những phần nào nên / phải để lại cho thử nghiệm của con người?

Ví dụ, nếu vòng lặp trò chơi được gói gọn trong một chức năng, có vẻ như sẽ rất khó để kiểm tra. Tôi muốn cấu trúc lại một chức năng "cập nhật" mất một khoảng thời gian và tiến về phía trước logic trò chơi; điều này cho phép một số thủ thuật thú vị như khả năng làm chậm trò chơi bằng cách cho nó ăn giả, thời gian chậm hơn.


6
Tại sao phải lãng phí thời gian viết bài kiểm tra đơn vị khi bạn có một đội quân lao động nô lệ gần như vô tận để làm trò chơi cho bạn? Tôi nhóc, tôi nhóc ...;)
Mike Strobel

1
Thật ra bạn không cần trẻ con, đó là một điểm rất tốt! Tôi đã không nghĩ về điều đó, nhưng trò chơi là loại phần mềm dễ nhất để người khác kiểm tra. Tôi đoán rằng phần nào bù đắp được khó khăn của thử nghiệm trò chơi tự động (đơn vị hoặc cách khác).
Ricket

3
Kiểm thử đơn vị không nhất thiết phải đảm bảo toàn bộ ứng dụng của bạn hoạt động chính xác (tức là kiểm tra chức năng). Đó là nhiều hơn về việc đảm bảo các thay đổi trong tương lai không phá vỡ chức năng hiện có. Chắc chắn, người dùng có thể thấy khi tàu vũ trụ lộn ngược, nhưng khi thuật toán đường dẫn tắt 0,001, các hiệu ứng có thể không rõ ràng cho đến khi trò chơi được chơi trong 200 giờ. Đó là loại điều mà các bài kiểm tra đơn vị có thể nắm bắt trước khi mã ra khỏi cửa.
Wade Williams

1
Trò chơi là phần mềm dễ nhất để khiến người dùng chơi , nhưng chơi! = Thử nghiệm . Nhận báo cáo lỗi tốt là khá khó. Ngoài ra, theo dõi nơi xảy ra lỗi trong mã và xác minh rằng các thay đổi mới không phá vỡ mã hiện có cả hai đều có lợi đáng kể từ các thử nghiệm tự động.
munificent

Câu trả lời:


25

Một trong những nguyên lý của TDD là bạn để TDD trong một số trường hợp ảnh hưởng đến thiết kế của bạn. Bạn viết một bài kiểm tra cho hệ thống, sau đó viết mã để thực hiện bài kiểm tra đó, giữ cho các phụ thuộc càng nông càng tốt.

Đối với tôi, chỉ có hai điều tôi không kiểm tra như một phần của kiểm tra đơn vị:

Đầu tiên, tôi không kiểm tra các yếu tố thị giác và mọi thứ trông như thế nào. Tôi kiểm tra và vật thể sẽ ở đúng vị trí sau khi nó cập nhật, rằng một camera sẽ loại bỏ một vật thể bên ngoài giới hạn của nó, biến đổi (ít nhất là những vật được thực hiện bên ngoài shader) được thực hiện đúng trước khi đưa vào công cụ đồ họa , nhưng một khi nó chạm vào hệ thống đồ họa, tôi vẽ đường thẳng. Tôi không thích thử chế giễu những thứ như DirectX.

Thứ hai, tôi không thực sự kiểm tra chức năng vòng lặp trò chơi chính. Tôi kiểm tra rằng mọi hệ thống sẽ hoạt động khi được thông qua một delta hợp lý và các hệ thống đó hoạt động chính xác khi chúng cần. Sau đó, tôi chỉ cập nhật từng hệ thống với delta chính xác trong vòng lặp trò chơi. Tôi thực sự có thể có một thử nghiệm để chỉ ra rằng mỗi hệ thống được gọi với delta chính xác, nhưng trong nhiều trường hợp tôi thấy rằng quá mức cần thiết (trừ khi bạn đang thực hiện logic phức tạp để có được delta của mình, thì nó không quá mức cần thiết).


6
Đoạn đầu tiên là chính. Thực tế là TDD yêu cầu bạn thiết kế mã của bạn tốt hơn bạn có mà không cần nó, chỉ đơn giản là cho phép thử nghiệm. Tất nhiên nhiều người nghĩ rằng họ là chuyên gia thiết kế, nhưng tất nhiên những người ấn tượng nhất với kỹ năng của họ thường là những người có nhiều thứ để học nhất ...
dash-tom-bang

2
Tôi sẽ không đồng ý rằng kết quả là mã được thiết kế tốt hơn. Tôi đã thấy rất nhiều điều ghê tởm khi một giao diện sạch trước đó phải được đập vỡ và đóng gói bị hỏng để tiêm các phụ thuộc có thể kiểm tra được.
Kylotan

4
Tôi thấy điều đó xảy ra nhiều hơn trong các trường hợp trong đó các bài kiểm tra được viết cho các lớp có sẵn hơn là theo cách khác.
Jeff

@Kylotan có lẽ đó là một triệu chứng của thiết kế không phù hợp / thiết kế thử nghiệm kém. Tái cấu trúc và sử dụng các giả để thực hiện các bài kiểm tra sạch, đừng hack mã của bạn vào trạng thái tồi tệ hơn; đó là điều ngược lại với những gì sẽ xảy ra
timoxley

2
Đóng gói là một điều tốt, nhưng điều quan trọng hơn là phải hiểu TẠI SAO nó là một điều tốt. Nếu bạn chỉ sử dụng nó để che giấu sự phụ thuộc và một giao diện xấu xí lớn, nó sẽ hét lên rất nhiều rằng thiết kế của bạn dưới mui xe có thể không đẹp lắm. Đóng gói chủ yếu không phải là để che giấu mã xấu và phụ thuộc, mà chủ yếu là làm cho mã của bạn dễ hiểu hơn và để người tiêu dùng có ít đường dẫn hơn để theo dõi khi anh ta cố gắng suy luận về mã.
Martin Odhelius

19

Noel Llopis đã bảo hiểm thử nghiệm đơn vị ở mức độ mà tôi tin rằng bạn đang tìm kiếm:

Đối với việc kiểm tra toàn bộ vòng lặp trò chơi, có một kỹ thuật khác để ngăn chặn hồi quy chức năng trong mã của bạn. Ý tưởng là để trò chơi của bạn tự chơi thông qua một hệ thống phát lại (ví dụ: đầu tiên ghi lại đầu vào của người chơi, sau đó phát lại chúng qua một lần chạy khác). Trong quá trình phát lại, bạn tạo một ảnh chụp nhanh về trạng thái của từng đối tượng cho mỗi khung hình. Bộ sưu tập nhà nước này sau đó có thể được gọi là "hình ảnh vàng". Khi cấu trúc lại mã của bạn, bạn chạy lại phát lại và so sánh từng trạng thái của khung hình với trạng thái hình ảnh vàng. Nếu nó khác, thử nghiệm đã thất bại.

Mặc dù lợi ích của kỹ thuật này là rõ ràng, có một số điều bạn cần cẩn thận:

  • Trò chơi của bạn cần có tính xác định, vì vậy bạn cần cẩn thận với những việc như tùy thuộc vào đồng hồ hệ thống, sự kiện hệ thống / mạng, trình tạo số ngẫu nhiên không được xác định hạt giống. v.v.
  • thay đổi nội dung sau khi hình ảnh vàng được tạo có thể gây ra sự khác biệt hợp pháp với hình ảnh vàng của bạn. Không có cách nào khắc phục điều này - khi thay đổi nội dung của bạn, bạn cần tạo lại hình ảnh vàng của mình.

+1 Cũng đáng lưu ý rằng giá trị của phương pháp này liên quan trực tiếp đến độ dài của "hình ảnh vàng": Nếu nó không đủ dài, bạn có thể dễ dàng bỏ lỡ lỗi; nếu quá lâu, bạn sẽ phải chờ đợi rất nhiều. Điều quan trọng là phải thử và khiến trò chơi chạy có lẽ nhanh hơn ở chế độ này, so với trong trường hợp thời gian chạy bình thường, để tắt thời gian. Bỏ qua kết xuất có thể giúp!
Kỹ sư

9

Tôi đồng ý với cả ý kiến ​​của Jeff và jpaver. Tôi cũng muốn thêm rằng việc áp dụng một mô hình thành phần cho kiến ​​trúc của bạn làm tăng đáng kể khả năng kiểm tra của nó. Với một mô hình thành phần, mỗi thành phần sẽ thực hiện một đơn vị công việc duy nhất và có thể kiểm tra được trong sự cô lập (hoặc với các đối tượng giả có giới hạn).

Tương tự như vậy, các phần khác của trò chơi dựa vào các thực thể chỉ nên dựa vào một tập hợp con của các thành phần để hoạt động. Trong thực tế điều này có nghĩa là bạn thường có thể giả lập một vài thành phần giả để tạo điều kiện kiểm tra các khu vực này hoặc bạn chỉ có thể soạn các thực thể một phần cho mục đích thử nghiệm. ví dụ: bạn bỏ qua các thành phần kết xuất và đầu vào vì chúng không cần thiết để kiểm tra vật lý.

Cuối cùng, tôi sẽ bỏ qua lời khuyên xung quanh hiệu suất mà bạn nhận được từ một số người trong cộng đồng trò chơi liên quan đến giao diện. Viết mã tốt với các giao diện và nếu bạn gặp vấn đề về hiệu năng, bạn có thể dễ dàng cấu hình, xác định và cấu trúc lại để giải quyết vấn đề. Tôi đã không bị thuyết phục bởi những lo ngại của Noel xung quanh tác động hiệu năng của các giao diện hoặc chi phí phức tạp mà họ đã thêm vào.

Điều đó nói rằng, đừng quá nhiệt tình cố gắng kiểm tra mọi thứ một cách độc lập. Giống như hầu hết mọi thứ kiểm tra và thiết kế là về sự cân bằng phù hợp.


Xin lưu ý, mặc dù bạn dường như không phải là người mới đối với SX, nhưng câu trả lời không được đặt hàng và nói điều gì đó như "cả hai ý kiến ​​trên" chắc chắn sẽ nhanh chóng bị phản đối, vì hiện tại bạn đang bỏ phiếu trước một của hai câu trả lời khác tại thời điểm này. :)
Ricket

Cảm ơn tôi đã không nghĩ về điều đó trong khi bình luận. Kể từ khi tôi cập nhật nhận xét để chọn ra từng nhận xét.
Alex Schearer

3

Tôi nghĩ rằng tôi sẽ thêm câu trả lời thứ hai trả lời bình luận của OP rằng người dùng có thể thay thế các bài kiểm tra đơn vị. Tôi tin rằng điều đó là hoàn toàn sai lầm vì mục đích của các bài kiểm tra đơn vị không phải là để đảm bảo chất lượng. Nếu bạn muốn kiểm tra tại chỗ để đảm bảo chất lượng chương trình của mình, bạn có thể nên điều tra kiểm tra kịch bản hoặc đầu tư vào giám sát tuyệt vời.

(Với sự giám sát tuyệt vời và một sản phẩm hoạt động như một dịch vụ, thực sự có thể đẩy một số "thử nghiệm" đến khách hàng nhưng bạn cần có một hệ thống tinh vi giúp phát hiện lỗi nhanh chóng và đẩy lùi các thay đổi có trách nhiệm. một nhóm phát triển nhỏ.)

Đơn vị kiểm tra lợi ích chính là họ buộc nhà phát triển viết mã được thiết kế tốt hơn. Hành động thử nghiệm thách thức nhà phát triển tách biệt mối quan tâm và đóng gói dữ liệu. Nó cũng khuyến khích nhà phát triển sử dụng các giao diện và các khái niệm trừu tượng khác để anh ta chỉ kiểm tra một thứ.


Đồng ý, ngoại trừ việc kiểm tra đơn vị không buộc các nhà phát triển viết mã tốt. Có một lựa chọn khác: các bài kiểm tra viết rất tệ. Bạn cần cam kết về ý tưởng kiểm tra đơn vị từ các lập trình viên của bạn để ngăn chặn chúng bị mờ.
tenpn

2
Chắc chắn nhưng đó không phải là lý do để ném em bé ra ngoài bằng nước tắm. Sử dụng các công cụ có trách nhiệm nhưng trước tiên sử dụng các công cụ.
Alex Schearer
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.