Kiểm thử đơn vị - Ứng dụng kết hợp cơ sở dữ liệu


15

Điều gì sẽ là cách tiếp cận tốt nhất khi thử nghiệm đơn vị một mô hình tích hợp vào một ứng dụng được kết hợp chặt chẽ với cơ sở dữ liệu?

Kịch bản cụ thể ở đây là một giỏ hàng - Tôi muốn có thể kiểm tra việc thêm và xóa các mục từ giỏ hàng cũng như logic về giá, v.v ... Điều này trong tâm trí tôi đều yêu cầu truy cập cơ sở dữ liệu mặc dù tôi đã đọc nhiều lần truy cập cơ sở dữ liệu nên tránh.


1
Thật thú vị khi các câu trả lời có hiệu quả "viết lại mã ứng dụng của bạn" được bình chọn
AD7six

Câu trả lời:


10

Phụ thuộc tiêm là một cách xử lý này. Bạn có thể thiết lập cơ sở dữ liệu thử nghiệm để bắt chước giỏ hàng hoặc thậm chí bạn có thể viết một số mã "xác nhận" giao dịch của khách hàng. Sau đó, trong thời gian chạy, phần mềm của bạn sẽ chọn thành phần nào để kết nối.

Chỉ cần không kết nối với cơ sở dữ liệu sản xuất cho bất cứ điều gì trong quá trình thử nghiệm!


1
Với DI và thiết kế ứng dụng phù hợp, bạn sẽ có thể kiểm tra mà không cần bất kỳ cơ sở dữ liệu nào --- miễn là bản giả mà bạn tiêm cung cấp đủ mô phỏng chi tiết của cơ sở dữ liệu phụ trợ.
Peter K.

4

Trong bài kiểm tra đơn vị, bạn phải xác định ranh giới của những gì bạn đang kiểm tra. Kiểm thử đơn vị khác với kiểm thử tích hợp. Nếu logic giá độc lập với nội dung Giỏ hàng, thì bạn kiểm tra riêng nó. Nếu đây không phải là trường hợp và tất cả các mô-đun được kết hợp chặt chẽ, hãy xây dựng một môi trường thử nghiệm bắt chước sản xuất nhiều nhất có thể và làm việc với điều đó. Tôi không tin rằng việc cắt ngắn và mô phỏng sẽ giúp về lâu dài.


2

Mô hình không nên phụ thuộc vào DB (cụ thể). Nếu nó chỉ biết một DB trừu tượng (đọc "giao diện") được trao cho mô hình thì bạn có thể thay thế DB bằng một đối tượng giả .

Trong lập trình hướng đối tượng , các đối tượng giả là các đối tượng mô phỏng mô phỏng hành vi của các đối tượng thực theo các cách được kiểm soát. Một lập trình viên thường tạo ra một đối tượng giả để kiểm tra hành vi của một số đối tượng khác, giống như cách mà một nhà thiết kế xe hơi sử dụng một hình nộm thử nghiệm va chạm để mô phỏng hành vi động của con người trong các tác động của xe ...


1

Tôi đã có một vấn đề tương tự - tôi không có khả năng đảm bảo DB thử nghiệm của tôi giữ các giá trị. Vì vậy, trong tương lai tôi nhận được ví dụ giá khác.

Tôi đã trích xuất dữ liệu tôi cần vào một sqlite nhỏ -DB và sử dụng DB này cho các thử nghiệm của mình. Test-DB hiện là một phần trong quá trình thiết lập bài kiểm tra đơn vị của tôi.


2
Điểm của các bài kiểm tra đơn vị là kiểm tra mã của bạn một cách cô lập. Nếu bạn sử dụng db sqllite thì nó không bị cô lập. Ngoài ra, sự không nhất quán giữa các cơ sở dữ liệu có thể gây ra lỗi
Tom Squires

0

"Tốt nhất" là chủ quan, nhưng bạn chỉ có thể sử dụng kết nối db thử nghiệm.

Sử dụng đồ đạc để tải một số dữ liệu thử nghiệm (ví dụ sản phẩm cần mua) và sau đó viết trường hợp thử nghiệm cho lớp / chức năng bạn muốn kiểm tra.


Việc mô tả các bài kiểm tra đơn vị kiểm tra một chức năng hoạt động trên cơ sở dữ liệu như các bài kiểm tra tích hợp là khá sai lệch @murph.
AD7six

1
Ok, bây giờ tôi vô cùng bối rối - nếu nó liên quan đến một cơ sở dữ liệu thì không phải theo hầu hết các định nghĩa, một bài kiểm tra đơn vị vì nó không bao gồm. Nếu bạn có một cơ sở dữ liệu thì bạn đang chạy thử nghiệm ở cấp độ cao hơn, một cơ sở dữ liệu phụ thuộc vào việc kết hợp các thứ "kết hợp". Bất kể điều này không phải là một lời giải thích rõ ràng cho tâm trí của tôi về cách giải quyết vấn đề.
Murph

0

Tôi đã xây dựng một plugin cho Symfony 1.4 (PHP) để giải quyết vấn đề này (trong số những thứ khác). Nó được mô hình hóa sau cách hoạt động của khung kiểm tra của Django (Python) : khung xây dựng và điền vào cơ sở dữ liệu kiểm tra riêng trước khi bắt đầu kiểm tra và phá hủy cơ sở dữ liệu kiểm tra sau khi hoàn thành mỗi kiểm tra.

Tôi có một vài lo ngại về chiến lược này, cả về hiệu suất (nếu lược đồ không thay đổi, tại sao không đơn giản xóa dữ liệu thay vì xây dựng lại toàn bộ cấu trúc?) Và sự thuận tiện (đôi khi tôi muốn kiểm tra cơ sở dữ liệu sau khi kiểm tra thất bại, vì vậy đừng phá hủy nó một cách bừa bãi!), vì vậy tôi đã thực hiện một cách tiếp cận hơi khác.

Trước khi thử nghiệm đầu tiên chạy, cơ sở dữ liệu bị hủy và được xây dựng lại, trong trường hợp đã có thay đổi mô hình kể từ lần thử nghiệm cuối cùng. Trước mỗi lần chạy thử tiếp theo, dữ liệu trong cơ sở dữ liệu sẽ bị xóa, nhưng cấu trúc không được xây dựng lại (mặc dù việc xây dựng lại thủ công có thể được kích hoạt từ một thử nghiệm nếu cần thiết).

Bằng cách tải có chọn lọc dữ liệu trong mỗi thử nghiệm, người ta có thể tạo môi trường thích hợp cho thử nghiệm đó mà không can thiệp vào các thử nghiệm tiếp theo. Các tập tin lịch thi đấu cũng có thể được sử dụng lại, điều này làm cho nhiệm vụ này ít gặp hơn (mặc dù đây vẫn là phần yêu thích nhất của tôi trong các bài kiểm tra viết!).

Trong cả hai khung kiểm tra, bộ điều hợp cơ sở dữ liệu được cấu hình để sử dụng kết nối thử nghiệm thay vì kết nối "sản xuất" để ngăn việc thực hiện kiểm tra làm hỏng dữ liệu hiện có.


0

Tôi muốn nói, chỉ cần tiếp tục và sử dụng đồ đạc để tải trước dữ liệu. Đó là cách các khung kiểm thử đơn vị dường như hoạt động nói chung, khi kiểm tra thao tác dữ liệu.

Nhưng nếu bạn thực sự muốn tránh phải kết nối với cơ sở dữ liệu dưới bất kỳ hình thức nào và đi theo định nghĩa quá nghiêm ngặt rằng các bài kiểm tra đơn vị không chạm vào bất cứ thứ gì bên ngoài mã, hãy xem chế độ chế nhạo đối tượng - nó có thể cho bạn ý tưởng.

Ví dụ, thay vì bỏ SQL trực tiếp vào mã nơi bạn cần, có một cách để gọi một phương thức chỉ thực hiện những gì SQL đó làm. Sử dụng Person.getPhoneNumber(), ví dụ, thay vì SELECT phone_number FROM person WHERE id = <foo>. Không chỉ đơn giản và dễ hiểu hơn trong nháy mắt, mà trong quá trình kiểm tra, bạn có thể giả định đối tượng Person để nó getPhoneNumber()luôn quay trở lại 555-555-5555hoặc một cái gì đó, thay vì chạm vào cơ sở dữ liệu.


0

Điều này khá dễ thực hiện với Junit nếu hơi dài dòng.

"Thiết lập" sẽ xác định và điền vào một tập hợp các bảng tạm thời.

Sau đó, bạn có thể thực hiện các bài kiểm tra đơn vị cho tất cả các chức năng cập nhật, chèn, xóa.

Đối với mỗi bài kiểm tra, bạn gọi phương thức cập nhật của mình, sau đó chạy một số SQL để xác minh kết quả mong đợi.

Trong giai đoạn "xé", bạn thả tất cả các bảng.

Theo cách này, bạn luôn chạy các bài kiểm tra tương tự trên cùng một dữ liệu ban đầu. Nếu bạn giữ các bảng giữa các lần kiểm tra thì cuối cùng chúng bị "ô nhiễm" bởi các thử nghiệm thất bại, thì thử nghiệm "chèn" nhất quán là gần như không thể vì bạn cần tiếp tục phát minh ra các khóa mới trong mỗi thử nghiệm.

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.