Gần đây, tôi đã hỏi (và trả lời) một câu hỏi về StackOverflow về lý do tại sao một bài kiểm tra đơn vị sẽ hoạt động khi tự chạy và sau đó không thường xuyên khi chạy với toàn bộ lô kiểm thử đơn vị. Xem tại đây: SQL Server and TransactionScope (with MSDTC): Sporadically can't get connectionBộ thu gom rác hoạt động như thế nào với các bài kiểm tra đơn vị?
Kiểm tra đơn vị đi qua khi chạy một lần và sau đó không thành công khi chạy cùng nhau là dấu hiệu cổ điển cho biết có điều gì đó nghiêm trọng sai với mã.
Tôi phát hiện ra rằng có một chút rò rỉ tài nguyên. Bởi vì một lỗi tinh vi gây ra các kết nối đến một máy chủ SQL không được phát hành, tôi đã chạy ra khỏi các kết nối và thử nghiệm đã thất bại. AFAIK, công trình này gần giống như rò rỉ bộ nhớ; các kết nối được cấp phát từ một hồ bơi kết nối và không bao giờ giải phóng cũng giống như bộ nhớ có thể được cấp phát và sau đó không được giải phóng.
Tuy nhiên, điều này khiến tôi có một câu hỏi khó hiểu? Sự khác nhau giữa việc chạy thử nghiệm của tôi từng cái một và chạy chúng như một bộ phần mềm là gì? Nếu các bài kiểm tra vượt qua khi chạy một lần và sau đó thất bại khi chạy cùng nhau, thì phải có một số loại dọn dẹp xảy ra giữa các lần chạy thử chỉ xảy ra khi các phép thử chạy một lần.
Tôi phỏng đoán rằng điều này có thể liên quan đến những gì trình thu thập rác .net thực hiện hoặc không thực hiện giữa các thử nghiệm. Trong một trường hợp, các kết nối được giải phóng giữa các thử nghiệm; trong trường hợp khác, họ không phải vậy.
Tôi làm cách nào để giải thích điều này?
Cập nhật: Để những người bạn hỏi về chi tiết cụ thể của mã này, nó khá đơn giản. Tôi khai báo một đối tượng TransactionScope
mới trong phương pháp Thiết lập của tôi và xử lý nó theo phương pháp Teardown
của tôi. Tuy nhiên, bài kiểm tra vấn đề là một thử nghiệm dựa trên dữ liệu với 100 trường hợp thử nghiệm; mã được thử nghiệm đã điền một đối tượng SqlDataReader
từ một câu lệnh chọn sử dụng lớp SqlHelper và sau đó không gọi phương thức đóng trên SqlDataReader
. Bởi vì tôi đã sử dụng lớp SqlHelper để có được SqlDataReader, tôi mong rằng các kết nối đã được xử lý cho tôi. Không phải vậy!
Nhưng để làm rõ, tôi không hỏi về trường hợp cụ thể của tôi. Điều tôi muốn biết là: thông thường, các nguồn lực được giải phóng như thế nào giữa các bài kiểm tra? Tôi sẽ tưởng tượng điều này sẽ là một số ứng dụng của bộ thu gom rác. Tôi tự hỏi liệu bộ thu gom rác vẫn có thể làm sạch một thử nghiệm trước đó khi chạy thử nghiệm tiếp theo (điều kiện chủng tộc?)
Cập nhật: Những gì tôi biết về thu gom rác với Bài kiểm tra đơn vị. Theo sự tò mò của riêng tôi, tôi đã rút ra các bài kiểm tra đơn vị đã thất bại vì một kết nối đã được mở bởi đối tượng SqlDataReader
. Tôi đã thử thêm System.GC.Collect()
vào cuối mỗi bài kiểm tra. Điều này đã giải phóng thành công các kết nối, nhưng áp đặt một hình phạt hiệu suất ~ 50%.
Nếu bạn đang hết kết nối vì bạn không phát hành đủ giữa các thử nghiệm, tôi nghi ngờ rằng có vấn đề với phương pháp rách. Khi chạy chúng cùng một lúc, hệ điều hành sẽ chăm sóc một số giọt nước mắt, nhưng chạy như một bộ sử dụng tài nguyên của bạn vẫn tồn tại lâu hơn. – MikeD
Có thể bạn chỉ cần thêm một số lệnh gọi 'Dispose' hoặc' Close' ở đâu đó? – Gabe