2012-08-17 25 views
7

Tôi đang đọc Clean Code: A Handbook of Agile Software Craftsmanship và một trong các ví dụ liên quan đến lớp học Portfolio và lớp học TokyoStockExchange. Tuy nhiên, Portfolio không phải là rất có thể kiểm chứng bởi vì nó phụ thuộc vào TokyoStockExchange làm API bên ngoài để xác định giá trị của danh mục đầu tư và đó là một tra cứu dễ bay hơi và không có lợi cho việc thử nghiệm.Bối rối về lý do tại sao nó hữu ích đối với các đối tượng giả thử nghiệm đơn vị

Vì vậy, chúng giải quyết vấn đề này bằng cách tạo giao diện chung StockExchange và có TokyoStockExchangeDummyStockExchange cả hai đều triển khai lớp cơ sở. Do đó, nguyên tắc nghịch đảo phụ thuộc được đạt tới và trong lớp PortfolioTest có thể khởi tạo DummyStockExchange, sửa giá cổ phiếu thành công ty, gán trường hợp DummyStockExchange vào danh mục và thêm một số cổ phiếu từ công ty đó vào danh mục, và sau đó xác nhận xem giá trị kỳ vọng thực sự là giá trị phù hợp. Đây là mã:

public class PortfolioTest 
{ 
    private DummyStockExchange exchange; 
    private Portfolio portfolio; 

    protected void setUp() 
    { 
     exchange = new DummyStockExchange(); 
     exchange.fix("MSFT", 100); 
     portfolio = new Portfolio(exchange); 
    } 

    public void GivenFiveMSFTTotalShouldBe500() 
    { 
     portfolio.add(5, "MSFT"); 
     Assert.assertEquals(500, portfolio.value()); 
    } 
} 

Câu hỏi của tôi, chỉ đơn giản là, là tại sao?

Chúng tôi đã thử nghiệm nếu lớp TokyoStockExchange hoạt động song song với lớp học Portfolio. Rõ ràng nếu chúng ta tạo ra một lớp khác với một phương pháp mới đặt giá cổ phiếu và sau đó cung cấp danh mục đầu tư năm trong số những cổ phiếu đó thì mọi thứ sẽ hoạt động. Nó chỉ có vẻ .. vô dụng để kiểm tra. Tôi hiểu rằng TokyoStockExchange về cơ bản là không thể kiểm tra với Portfolio vì giá cổ phiếu thay đổi nhưng tôi không hiểu làm thế nào subbing trong một thử nghiệm khá vô ích giúp tình hình. Tất cả chỉ có vẻ như không biết liệu chương trình bổ trợ của chúng tôi có hoạt động hay không nhưng chỉ có các số duy nhất được tạo ngẫu nhiên để chúng tôi tạo một lớp giả cho chúng ta 2 và kiểm tra nếu 2 + 2 = 4. Vâng vâng, rõ ràng đó là sự thật. Chúng tôi vẫn có thể vi phạm TokyoStockExchange và thử nghiệm sẽ vẫn thành công vì thử nghiệm một lớp khác. Nếu bất cứ điều gì tất cả điều này có vẻ lừa đảo và nó cũng dẫn đến việc phải viết mã bổ sung chỉ để kiểm tra một cái gì đó chúng ta biết là sẽ làm việc.

Tôi nghĩ đây là vấn đề lớn nhất mà tôi có với sự hiểu biết về Kiểm thử đơn vị tại thời điểm này. Tôi biết rằng tôi sai, tôi đã không nhìn thấy ánh sáng tôi đoán. Hy vọng rằng ai đó có thể giúp tôi ra.

+0

Để tham khảo ... nếu bạn đang thử nghiệm 'TokyoStockExchange' hoạt động * với *' Danh mục đầu tư', bạn nằm ngoài phạm vi kiểm tra đơn vị. 'Portfolio' và' TokyoStockExchange' là các đơn vị, và thử nghiệm đơn vị được thiết kế để kiểm tra từng đơn vị * riêng biệt với nhiều đơn vị khác nhất có thể (tốt nhất là tất cả). Sự tương tác giữa chúng là những gì * kiểm tra tích hợp * bao gồm. – cHao

+2

+1 để cố gắng hiểu giá trị chứ không phải là thổi tắt thử nghiệm đơn vị với "đó là nhiều công việc để duy trì mã đó, quá" –

+0

Đây thực sự là một câu hỏi cho [programmers.se]. –

Trả lời

7

Ý tưởng là bạn sẽ muốn kiểm tra logic trong lớp Portfolio cách ly khỏi TokyoStockExchange. Nếu bạn sử dụng khung giả như Moq hoặc Rhino Mocks, bạn có thể dễ dàng mô phỏng các đầu ra và hành vi khác nhau từ TokyoStockExchange và viết các bài kiểm tra đơn vị để đảm bảo rằng Portfolio phản hồi chính xác. Bạn sẽ viết các bài kiểm tra đơn vị riêng biệt cho lớp học TokyoStockExchange.

Điều này không có nghĩa là bạn không cần tích hợp kiểm tra giữa hai lớp. Thật khó để xác minh đúng tất cả các kịch bản mà không sử dụng các đối tượng giả. Thật khó để hiểu được giá trị với một lớp đơn giản như một ví dụ, nhưng đưa ra một lớp phức tạp hơn, nơi bạn cần phải xác minh các trường hợp thử nghiệm cho các tình huống khó hoặc không thể sắp xếp trên một lớp "sống", đơn vị thử nghiệm trở nên quan trọng hơn nhiều.

+3

+1 Chính xác. Bạn không thử nghiệm TokyoStockExchange, bạn đang thử nghiệm rằng lớp Portfolio hoạt động chính xác. – CaffGeek

+0

Để thêm: Bạn muốn kiểm tra cách ly vì vậy khi thử nghiệm không thành công, bạn sẽ dễ dàng tìm ra nguyên nhân gốc rễ hơn. Nếu bạn chạy thử nghiệm tích hợp với 20 lớp khác nhau trong trò chơi và nó "không thành công", bạn có thể dành rất nhiều thời gian xem qua 20 lớp học vì nguyên nhân gốc rễ. Nếu bạn bung ra một bó (như 19) và giảm độ chi tiết xuống một lớp, bạn sẽ giảm đáng kể diện tích bề mặt mà bạn phải tìm kiếm/sửa chữa. –

+0

Ngoài ra, bằng cách tạo ** phụ thuộc ** được biết tuyệt đối, bạn có thể xóa ** biến đổi ** khỏi câu hỏi của bài kiểm tra. Điều này tạo ra một đường cơ sở mà từ đó bạn có thể nói "đối tượng này hoạt động chính xác như mong đợi khi được đưa ra tiêu chuẩn hoặc đầu vào dự kiến." Thay vào đó, hãy xem xét rằng sự phụ thuộc tạo ra một kết nối cơ sở dữ liệu nhưng kết nối đó không thành công vì một số lý do ... bạn không muốn thử nghiệm này thất bại vì đó không phải là đại diện cho những gì bạn đang thử nghiệm. –

3

Có hai loại kiểm tra bạn nên thực hiện, kiểm tra đơn vị và thử nghiệm tích hợp.

Thử nghiệm đơn vị được coi là thử nghiệm hộp trắng, trong đó bạn kiểm tra từng đơn vị mã trong sự cô lập. Nói chung điều này đề cập đến giao diện công khai của bạn trong mỗi lớp.Bạn giả lập các phụ thuộc của họ để bạn được đảm bảo rằng được cung cấp một bộ dữ liệu đã biết, đơn vị của bạn sẽ trả về các kết quả có thể dự đoán được.

Bạn nói, "rõ ràng mọi thứ sẽ hoạt động" trong bài kiểm tra đơn vị. Điều đó giả định rằng bạn không có bất kỳ lỗi nào trong mã của bạn. Nếu bạn có thể đưa ra giả định đó thì bạn sẽ không cần kiểm tra bất cứ thứ gì ngay từ đầu! Và bạn thực sự không cần đơn vị kiểm tra mọi thứ --- nếu Portfolio của bạn chỉ là một lớp mỏng trên đầu trang StockExchange gọi các phương thức API và chuyển qua kết quả, bạn không nên bận tâm đến việc kiểm thử đơn vị đó.

Mặt khác, nếu Portfolio của bạn có logic thực sự trong đó, bạn sẽ muốn đơn vị kiểm tra nó. Giả sử Portfolio có phương pháp lấy dữ liệu từ Stock Exchange, phân tích dữ liệu và gửi thông báo cảnh báo tới người dùng khi giá cổ phiếu hiển thị một số bất thường, chẳng hạn như nếu giá bắt đầu giảm nhanh. Bạn muốn đảm bảo rằng cảnh báo thực sự sẽ được kích hoạt được gửi trong điều kiện dự kiến, nhưng bạn không muốn ngồi xung quanh và chờ đợi sự sụp đổ của thị trường chứng khoán tiếp theo. Vì vậy, trong thử nghiệm đơn vị của bạn, bạn sẽ thực hiện một mô hình Stock Exchange tạo ra các loại giá trị mà bạn muốn kích hoạt cảnh báo và sau đó kiểm tra xem nó có thực sự xảy ra hay không. Nếu có, tuyệt vời, nếu không, bạn chỉ tìm thấy một lỗi.

Thử nghiệm tích hợp sẽ kiểm tra hai đơn vị song song và cũng rất quan trọng. Nhưng sẽ khó mô phỏng một số loại kịch bản nhất định trong thử nghiệm tích hợp và sẽ ít hữu ích hơn trong việc tìm ra nơi một lỗi thực sự ẩn. Nếu bạn chạy thử nghiệm tích hợp cho ứng dụng của mình và nhận thấy rằng nó không gửi thông báo khi cần, thì sự cố ở đâu? Có lỗi trong API của bên thứ ba không? Sàn giao dịch chứng khoán có gửi cho bạn các giá trị xấu không? Hệ thống cảnh báo của bạn có gửi tin nhắn sai địa chỉ không? Có thể mất một lúc để bạn tìm ra rằng có vấn đề với phương pháp phân tích của bạn.

Các vấn đề liên quan