Làm thế nào để tạo các thử nghiệm tích hợp miễn phí có thể mở rộng và hiệu ứng phụ?


14

Trong dự án hiện tại của tôi, tôi đang gặp khó khăn khi đưa ra một giải pháp tốt để tạo ra các thử nghiệm tích hợp có thể mở rộng mà không có tác dụng phụ. Một chút làm rõ về thuộc tính miễn phí hiệu ứng phụ: chủ yếu là về cơ sở dữ liệu; không nên có bất kỳ thay đổi nào trong cơ sở dữ liệu sau khi các bài kiểm tra được hoàn thành (trạng thái cần được bảo tồn). Có thể khả năng mở rộng và bảo tồn nhà nước không đi cùng nhau, nhưng tôi thực sự muốn thúc đẩy một giải pháp tốt hơn.

Đây là một thử nghiệm tích hợp điển hình (các thử nghiệm này chạm vào lớp cơ sở dữ liệu):

public class OrderTests {

    List<Order> ordersToDelete = new ArrayList<Order>(); 

    public testOrderCreation() {
        Order order = new Order();
        assertTrue(order.save());
        orderToDelete.add(order);
    }

    public testOrderComparison() {
        Order order = new Order();
        Order order2 = new Order();
        assertFalse(order.isEqual(order2);
        orderToDelete.add(order);
        orderToDelete.add(order2);
    }
    // More tests

    public teardown() {
         for(Order order : ordersToDelete)
             order.delete();
    }
}

Như người ta có thể tưởng tượng, phương pháp này mang lại các bài kiểm tra cực kỳ chậm. Và, khi áp dụng cho toàn bộ các thử nghiệm tích hợp, chỉ mất khoảng 5 giây để kiểm tra một phần nhỏ của hệ thống. Tôi có thể tưởng tượng con số này sẽ tăng lên khi phạm vi bảo hiểm được tăng lên.

Điều gì sẽ là một cách tiếp cận khác để viết các bài kiểm tra như vậy? Một cách khác tôi có thể nghĩ đến là có loại biến toàn cục (trong một lớp) và tất cả các phương thức kiểm tra đều chia sẻ biến này. Kết quả là chỉ có vài đơn hàng được tạo & xóa; dẫn đến các bài kiểm tra nhanh hơn. Tuy nhiên, tôi nghĩ rằng điều này giới thiệu một vấn đề lớn hơn; các bài kiểm tra không còn bị cô lập và ngày càng khó hiểu và phân tích chúng.

Nó có thể chỉ là các thử nghiệm tích hợp không có nghĩa là được chạy thường xuyên như các thử nghiệm đơn vị; do đó hiệu suất thấp có thể được chấp nhận cho những người. Trong mọi trường hợp, sẽ rất tuyệt nếu biết ai đó đã đưa ra các giải pháp thay thế để cải thiện khả năng mở rộng.

Câu trả lời:


6

Xem xét việc sử dụng Hypersonic hoặc DB trong bộ nhớ khác để kiểm tra đơn vị. Không chỉ các xét nghiệm sẽ thực hiện nhanh hơn, mà các tác dụng phụ không liên quan. (Quay ngược lại các giao dịch sau mỗi thử nghiệm cũng cho phép chạy nhiều thử nghiệm trên cùng một ví dụ)

Điều này cũng sẽ buộc bạn tạo các mockup dữ liệu, đó là một điều tốt IMO, vì nó có nghĩa là một cái gì đó xảy ra trên cơ sở dữ liệu sản xuất không thể bắt đầu thất bại trong các thử nghiệm của bạn, và nó cung cấp cho bạn một điểm khởi đầu cho "cài đặt cơ sở dữ liệu sạch "Sẽ giống như, điều này giúp nếu bạn cần đột nhiên triển khai một phiên bản mới của ứng dụng mà không có kết nối với trang web sản xuất hiện tại của bạn.

Có, tôi tự sử dụng phương pháp này và vâng, đó là Pita để thiết lập thời gian ĐẦU TIÊN, nhưng nó được trả nhiều hơn cho chính nó trong suốt thời gian của dự án tôi sắp hoàn thành. Ngoài ra còn có một số công cụ trợ giúp cho các mockup dữ liệu.


Nghe có vẻ như một ý tưởng tuyệt vời. Tôi đặc biệt thích khía cạnh cô lập hoàn toàn của nó; bắt đầu với một cài đặt cơ sở dữ liệu mới. Có vẻ như sẽ mất một số nỗ lực, nhưng một khi thiết lập, nó sẽ rất có lợi. Cảm ơn.
Guven

3

Đây là vấn đề muôn thuở mà mọi người phải đối mặt trong khi viết các bài kiểm tra tích hợp.

Giải pháp lý tưởng, đặc biệt nếu bạn đang thử nghiệm sản xuất, đang mở một giao dịch trong thiết lập và khôi phục lại. Tôi nghĩ rằng điều này nên phù hợp với nhu cầu của bạn.

Nếu không thể, ví dụ khi bạn đang kiểm tra ứng dụng từ lớp máy khách, một giải pháp khác là sử dụng DB trên máy ảo và chụp ảnh nhanh trong thiết lập và quay lại ứng dụng (không thành công mất bao lâu bạn có thể mong đợi).


Tôi không thể tin rằng tôi đã không nghĩ đến việc khôi phục giao dịch. Tôi sẽ sử dụng ý tưởng đó như một giải pháp nhanh chóng cho giải pháp, nhưng cuối cùng DB trong bộ nhớ nghe có vẻ rất hứa hẹn.
Guven

3

Kiểm tra tích hợp phải luôn luôn được chạy với thiết lập sản xuất. Trong trường hợp của bạn, điều đó có nghĩa là bạn nên có cùng cơ sở dữ liệu và máy chủ ứng dụng. Tất nhiên, vì mục đích hiệu năng, bạn có thể quyết định sử dụng DB trong bộ nhớ.

Điều bạn không bao giờ nên làm là mở rộng phạm vi giao dịch của mình. Một số người đề nghị kiểm soát giao dịch và hoàn trả lại sau khi thử nghiệm. Khi bạn thực hiện việc này, tất cả các thực thể (giả sử bạn đang sử dụng JPA) sẽ gắn liền với bối cảnh tồn tại trong suốt quá trình thực hiện kiểm tra. Điều này có thể dẫn đến một số lỗi rất khó chịu mà rất khó tìm .

Thay vào đó, bạn nên xóa cơ sở dữ liệu theo cách thủ công sau mỗi lần kiểm tra thông qua thư viện như JPAUnit hoặc tương tự với phương pháp này (xóa tất cả các bảng bằng JDBC).

Đối với các vấn đề về hiệu suất của bạn, bạn không nên thực hiện các bài kiểm tra tích hợp trên mỗi bản dựng. Hãy để máy chủ tích hợp liên tục của bạn làm điều này. Nếu bạn sử dụng Maven, bạn có thể tận hưởng trình cắm không an toàn cho phép bạn tách các bài kiểm tra của mình thành các bài kiểm tra đơn vị và tích hợp.

Ngoài ra, bạn không nên chế giễu bất cứ điều gì. Hãy nhớ rằng bạn đang kiểm tra tích hợp, tức là kiểm tra hành vi trong môi trường thực thi thời gian chạy.


Câu trả lời tốt. Một điểm: Có thể chấp nhận giả định một số phụ thuộc bên ngoài (ví dụ gửi email). Nhưng bạn không nên giả định bằng cách thiết lập một dịch vụ / máy chủ giả hoàn chỉnh, chứ không phải giả lập nó trong mã Java.
sleske

Sleske, tôi đồng ý với bạn. Đặc biệt là khi bạn đang sử dụng JPA, EJB, JMS hoặc thực hiện theo thông số kỹ thuật khác. Bạn có thể trao đổi máy chủ ứng dụng, nhà cung cấp kiên trì hoặc cơ sở dữ liệu. Chẳng hạn, bạn có thể muốn sử dụng Glassfish và HSQLDB nhúng để chỉ cần thiết lập và cải thiện tốc độ (tất nhiên bạn có thể tự do chọn một triển khai được chứng nhận khác).
BenR

2

Về khả năng mở rộng

Tôi đã gặp vấn đề này một vài lần trước đây, rằng các thử nghiệm tích hợp đã mất quá nhiều thời gian để chạy và không thực tế đối với một nhà phát triển duy nhất liên tục chạy trong một vòng phản hồi chặt chẽ về các thay đổi. Một số chiến lược để đối phó với điều này là:

  • Viết ít kiểm tra tích hợp hơn - nếu bạn có phạm vi bảo hiểm tốt với các kiểm tra đơn vị trong hệ thống, các kiểm tra tích hợp nên tập trung hơn vào các vấn đề tích hợp (ahem), về cách các thành phần khác nhau làm việc cùng nhau. Chúng giống với các thử nghiệm khói hơn, chỉ cần thử xem hệ thống có còn hoạt động không. Vì vậy, lý tưởng nhất là các bài kiểm tra đơn vị của bạn bao gồm hầu hết các phần chức năng của ứng dụng và các bài kiểm tra tích hợp chỉ kiểm tra cách các phần đó tương tác với nhau. Bạn không cần bảo hiểm rộng rãi về các đường dẫn logic ở đây, chỉ cần một số đường dẫn quan trọng thông qua hệ thống.
  • Chỉ chạy một tập hợp con các bài kiểm tra tại một thời điểm - vì một nhà phát triển duy nhất làm việc trên một số chức năng, bạn thường có ý thức về các bài kiểm tra nào là cần thiết để bao quát chức năng đó. Chỉ chạy những bài kiểm tra có ý nghĩa để bao gồm những thay đổi của bạn. Các khung như JUnit cho phép bạn nhóm các đồ đạc trong một danh mục . Tạo các nhóm cho phép bảo hiểm tốt nhất cho từng tính năng mà bạn có. Tất nhiên, bạn vẫn muốn chạy tất cả các thử nghiệm tích hợp tại một số điểm, có thể trước khi cam kết với hệ thống kiểm soát nguồn và chắc chắn tại máy chủ tích hợp liên tục.
  • Tối ưu hóa hệ thống - Các thử nghiệm tích hợp cùng với một số thử nghiệm hiệu suất có thể cung cấp cho bạn đầu vào cần thiết để điều chỉnh các phần chậm của hệ thống, để các thử nghiệm sẽ chạy nhanh hơn sau này. Điều này có thể giúp khám phá các chỉ mục cần thiết trong cơ sở dữ liệu, giao diện trò chuyện giữa các hệ thống con hoặc các tắc nghẽn hiệu suất khác cần giải quyết.
  • Chạy các bài kiểm tra của bạn song song - Nếu bạn có một nhóm các bài kiểm tra trực giao tốt, bạn có thể thử chạy chúng song song . Hãy chú ý đến yêu cầu trực giao mà tôi đã đề cập, bạn không muốn các bài kiểm tra của mình bước vào chân nhau.

Hãy thử kết hợp các kỹ thuật này để có hiệu quả cao hơn.


1
Hướng dẫn thực sự tốt; viết ít bài kiểm tra tích hợp là chắc chắn lời khuyên tốt nhất. Ngoài ra, chạy chúng song song sẽ là một lựa chọn rất tốt; một "bài kiểm tra" hoàn hảo để kiểm tra xem tôi có kiểm tra thẳng về mặt cách ly hay không.
Guven

2

Đối với mục đích thử nghiệm, chúng tôi đã sử dụng một triển khai dựa trên tệp của cơ sở dữ liệu SQLite (chỉ cần sao chép tài nguyên). Điều này đã được thực hiện để chúng tôi cũng có thể kiểm tra di chuyển lược đồ. Theo như tôi biết, các thay đổi lược đồ không phải là giao dịch nên sẽ không được khôi phục sau khi giao dịch bị hủy bỏ. Ngoài ra, không phải phụ thuộc vào hỗ trợ giao dịch để thiết lập thử nghiệm cho phép kiểm tra hành vi của các giao dịch từ ứng dụng của bạn đúng cách.

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.