Tại sao nên sử dụng cơ sở dữ liệu trong bộ nhớ để kiểm tra tích hợp?


18

Tôi thực sự bối rối khi thấy rất nhiều triển khai cơ sở dữ liệu trong bộ nhớ được sử dụng để thử nghiệm, bởi vì tôi cũng đã nghe rất nhiều từ các thực tiễn tốt nhất về kiểm thử tích hợp rằng môi trường chạy thử nghiệm phải giống với môi trường sản xuất nhất, bao gồm cả hệ điều hành , thư viện, công cụ cơ sở dữ liệu, v.v.

Tôi đang thiếu gì ở đây?


Tôi đã thấy nó rất nhiều bởi vì bạn có thể lập trình đảm bảo tính nhất quán của dữ liệu cộng với chúng thường khá nhanh. Đặc biệt nếu bài kiểm tra của bạn là bài kiểm tra đơn vị, bạn muốn nó là một hệ thống khép kín. Bạn muốn các bài kiểm tra của bạn được bao gồm hoàn toàn trong bài kiểm tra.
Giàn khoan

Thật tuyệt khi một nhà phát triển có thể nhận được mã mới nhất và chạy thử nghiệm mà không cần phải thiết lập cơ sở dữ liệu bên ngoài trước đó.
Jason Evans

1
Theo tôi, các khía cạnh đòi hỏi gần giống với môi trường sản xuất thuộc về kiểm tra tải trọng và kiểm tra căng thẳng, cần được thực hiện tách biệt với kiểm tra đơn vị (như một tiêu chí cam kết mã cổng) theo ý kiến ​​của tôi.
rwong

Câu trả lời:


19

Trong một tình huống phát triển phần mềm điển hình, các thử nghiệm được sử dụng ở hai điểm: trong quá trình phát triển và trước khi di chuyển sản phẩm theo chuỗi phát triển.

Tình huống đầu tiên, chạy thử nghiệm trong quá trình phát triển, phục vụ các mục tiêu ngắn hạn: xác định các nhiệm vụ (như trong TDD: viết thử nghiệm thất bại, sau đó vượt qua), ngăn chặn hồi quy, đảm bảo các thay đổi của bạn không phá vỡ bất cứ điều gì khác, v.v. các bài kiểm tra cần phải cực kỳ nhanh: lý tưởng là toàn bộ bộ kiểm tra của bạn chạy trong chưa đầy 5 giây và bạn chỉ có thể chạy nó trong một vòng lặp bên cạnh IDE hoặc trình soạn thảo văn bản trong khi bạn viết mã. Bất kỳ hồi quy nào bạn giới thiệu sẽ bật lên trong vòng vài giây. Chạy thử nghiệm nhanh là quan trọng trong giai đoạn này hơn là bắt được 100% hồi quy và lỗi và vì nó không thực tế (hoặc hoàn toàn không thể) để phát triển trên các bản sao chính xác của hệ thống sản xuất, nên nỗ lực để đạt được thử nghiệm hoàn hảo ở đây không đáng nó Sử dụng cơ sở dữ liệu trong bộ nhớ là một sự đánh đổi: chúng không phải là bản sao chính xác của hệ thống sản xuất, nhưng chúng giúp giữ cho các bài kiểm tra chạy dưới giới hạn 5 giây; nếu sự lựa chọn nằm giữa một thiết lập cơ sở dữ liệu hơi khác nhau cho thử nghiệm liên quan đến cơ sở dữ liệu của tôi và không có thử nghiệm nào cả, tôi biết tôi chọn gì.

Tình huống thứ hai, di chuyển mã dọc theo chuỗi phát triển, tuy nhiên, không đòi hỏi phải thử nghiệm rộng rãi. Vì chúng tôi có thể (và nên) tự động hóa phần này của quá trình phát triển, chúng tôi có thể đủ khả năng kiểm tra chậm hơn nhiều - ngay cả khi chạy thử đầy đủ mất hàng giờ, lên lịch xây dựng hàng đêm vẫn có nghĩa là chúng tôi luôn có một bức tranh chính xác về cơ sở mã của ngày hôm qua. Mô phỏng môi trường sản xuất chính xác nhất có thể là điều quan trọng hiện nay, nhưng chúng ta có thể mua được. Vì vậy, chúng tôi không tạo ra sự đánh đổi trong cơ sở dữ liệu trong bộ nhớ: chúng tôi cài đặt cùng một phiên bản chính xác của DBMS giống như các hệ thống sản xuất và nếu có thể, chúng tôi sẽ điền vào dữ liệu sản xuất thực tế trước khi bắt đầu thử nghiệm.


6

Tôi đoán đó là một tốc độ đánh đổi / phù hợp với môi trường. Các bài kiểm tra nên được chạy thường xuyên, và điều đó có nghĩa là chúng phải nhanh. Đặc biệt là các bài kiểm tra đơn vị, không nên mất nhiều hơn một vài giây.

Kiểm tra tích hợp sẽ chạy chậm hơn, nhưng khi chúng nhanh, bạn có thể chạy chúng thường xuyên hơn. Ví dụ, trước mỗi cam kết. Tất nhiên, nó không hoàn chỉnh như một môi trường đầy đủ, nhưng ít nhất bạn đang kiểm tra lớp ánh xạ, SQL được tạo, cách các phần nói chuyện với nhau, v.v. Trong trường hợp cơ sở dữ liệu tốn kém, bạn cũng đảm bảo rằng bạn không ' t cần mua giấy phép cho mọi người Bạn có thể bắt gặp nhiều lỗi hơn bao gồm 90% mã với các thử nghiệm được chạy một lần mỗi giờ so với bao phủ 100% thử nghiệm mã một lần mỗi ngày hoặc tệ nhất trong tuần.

Điều đó đang được nói, tất nhiên bạn cần thử nghiệm với cơ sở dữ liệu thực và môi trường tích hợp đầy đủ. Bạn có thể không chạy các bài kiểm tra đó thường xuyên, nhưng vì bài kiểm tra trước của bạn đã mang lại cho bạn sự tự tin, tất cả những gì còn lại là lỗi cụ thể của nền tảng.


3

Để thực hiện các thử nghiệm đơn giản, việc nhét lớp truy cập cơ sở dữ liệu là hoàn toàn chấp nhận được. Bạn gọi getName(), nó gọi DAO đã bị chế giễu và trả lại "John" cho tên đầu tiên và "Smith" cho tên cuối cùng, lắp ráp chúng và mọi thứ đều hoàn hảo. Không cần phải thực sự đơn vị kiểm tra một cơ sở dữ liệu ở đó.

Mọi thứ trở nên phức tạp hơn một chút khi logic trở nên phức tạp hơn một chút. Điều gì sẽ xảy ra nếu bạn có một phương thức "createdOrUpdateUser (...)". Nếu bạn giả định cơ sở dữ liệu, bạn có thể xác minh rằng một phương thức đã cho đã được gọi một lần với một tham số nhất định khi giả định trả về không có đối tượng và một phương thức khác được gọi trên cơ sở dữ liệu khi nó trả về một đối tượng hiện có. Điều này bắt đầu đi đến dòng mờ nơi mà nó có thể dễ dàng hơn (đặc biệt là nếu nó đã có) để tạo ra một cơ sở dữ liệu bộ nhớ chuyên dụng và kiểm tra mã đó với dữ liệu được cấu hình sẵn.

Trong một số mã thực tế tôi đã làm việc (điểm bán hàng), chúng tôi đã có một resumeSuspededTransaction(...)phương pháp. Điều này sẽ kéo giao dịch từ cơ sở dữ liệu vào một đối tượng (và các thành phần của nó) và cập nhật cơ sở dữ liệu. Chúng tôi đã chế giễu và một lỗi đã ẩn trong mã ở đâu đó với việc tuần tự hóa và giải tuần tự hóa dữ liệu đi đến cơ sở dữ liệu (chúng tôi đã thay đổi một loại được tuần tự hóa khác nhau trên cơ sở dữ liệu).

Giả đã không cho chúng ta thấy lỗi vì nó đang trả lại con đường hạnh phúc của nó - tuần tự hóa giao dịch, lưu trữ nó trong giả, giải tuần tự hóa nó khỏi giả, kiểm tra xem chúng có bằng nhau không. Tuy nhiên, khi bạn tuần tự hóa một đối tượng có số 0 dẫn đến cơ sở dữ liệu, nó sẽ thả chúng và sau đó kết hợp lại thành một chuỗi không có số không. Chúng tôi đã bắt lỗi mà không có cơ sở dữ liệu thông qua khắc phục sự cố (không khó để phát hiện ra một khi chúng tôi biết nó ở đó).

Sau đó, chúng tôi đặt một cơ sở dữ liệu vào đó và nhận ra rằng lỗi sẽ không bao giờ vượt qua bài kiểm tra cơ sở đó nếu chúng ta thay vào đó là đi đến cơ sở dữ liệu bộ nhớ.


Trong cơ sở dữ liệu bộ nhớ có những ưu điểm:

  • chúng có thể được tạo ra nhanh chóng (mà không cần DBA để thiết lập tài khoản, bảng và như vậy) để thử nghiệm
  • dữ liệu có thể được cấu hình sẵn cho thử nghiệm đó
  • bài kiểm tra không cần phải lo lắng về việc hoàn thành bài kiểm tra khi hoàn thành
  • mỗi bài kiểm tra có cơ sở dữ liệu bộ nhớ riêng, do đó bạn không phải lo lắng nếu hai bài kiểm tra đang chạy cùng một lúc
  • chúng có thể được chạy trên các hệ thống không có kết nối với cơ sở dữ liệu thực

1

Điều này phụ thuộc nhiều vào hệ thống cơ sở dữ liệu bạn đang sử dụng. Khi hệ thống db của bạn cung cấp cho bạn một giải pháp thay thế trong bộ nhớ gần như 100% API hành vi tương thích với cấu hình cơ sở dữ liệu dựa trên đĩa (ngoại trừ tốc độ và lỗi không an toàn, hoặc khóa học), thì sử dụng biến thể trong bộ nhớ rõ ràng là tốt .

Tuy nhiên, nếu hệ thống DB của bạn có sự khác biệt đáng kể giữa cấu hình trong bộ nhớ và sử dụng không trong bộ nhớ, bạn đã đúng: trong trường hợp này, các kiểm tra tích hợp có nguy cơ bị lỗi cao hơn. Nhưng ngay cả khi đó, bạn có thể tự mình "trừu tượng hóa sự khác biệt đó", cho bạn biết rõ hệ thống DB của mình và sự khác biệt.


1

Theo cách nói của giáo dân:

Việc chế nhạo các phần quan trọng của kiến ​​trúc là OK (và phải) để thử nghiệm đơn vị .

Nhưng để thử nghiệm tích hợp, tôi hoàn toàn đồng ý với bạn. Mocking không nên được thực hiện và một môi trường tương tự như có thể được cung cấp.

Xét cho cùng, các thử nghiệm tích hợp là về thử nghiệm các phần khác nhau của kiến ​​trúc hoạt động như thế nào.

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.