2012-04-23 31 views
8

Giả sử bạn có một trang web, sử dụng một hàm để truy xuất dữ liệu từ cơ sở dữ liệu và trả lại kết quả được hiển thị/phân tích/...Làm thế nào để viết bài kiểm tra đơn vị cho các chức năng dựa trên dữ liệu động?

Vì dữ liệu được lấy từ cơ sở dữ liệu là động và có thể có khả năng thay đổi mỗi giây trong ngày, làm thế nào để bạn viết đúng Bài kiểm tra Đơn vị cho chức năng này?

Giả sử hàm được cho là trả về một loạt các kết quả. Rõ ràng là một bài kiểm tra đơn vị có thể kiểm tra xem một mảng có được trả về hay không. Nhưng điều gì sẽ xảy ra khi nội dung của chính mảng đó không chính xác do một truy vấn MySQL được viết sai? Kích thước của mảng có thể bằng không hoặc nội dung của mảng có thể không chính xác. Vì nó dựa trên dữ liệu luôn thay đổi, làm thế nào để Unit Test biết cái gì là đúng và cái gì không? Các cuộc gọi đến cơ sở dữ liệu từ bên trong Test Unit chính nó có cần thiết cho nên có cái gì đó để so sánh nó với?

Làm thế nào để bạn viết đúng Bài kiểm tra đơn vị cho các hàm dựa trên dữ liệu động?

+0

Điều này có thể thú vị: http://blog.schauderhaft.de/2011/03/13/testing-databases-with-junit-and -hibernate-part-1-one-to-rule-them/ –

Trả lời

7

Xét nghiệm đơn vị, ở dạng lý tưởng của họ, chỉ nên kiểm tra một điều. Trong trường hợp này, bạn đang thử nghiệm hai điều:

  1. logic của hàm của bạn
  2. việc thu hồi cơ sở dữ liệu

Vì vậy, tôi sẽ đề nghị các cấu trúc lại sau:

  1. Di chuyển logic truy xuất cơ sở dữ liệu vào một hàm riêng biệt
  2. Có chức năng bạn muốn kiểm tra cuộc gọi chức năng khác
  3. Giả sử hàm trả về dữ liệu để bạn có thể kiểm tra đơn vị logic của ứng dụng
  4. Nếu có ý nghĩa (nếu bạn chỉ dựa vào thư viện khác để thực hiện điều này, thì hy vọng rằng lib đã có kiểm tra), viết một bài kiểm tra đơn vị cho chức năng truy hồi động, nơi bạn không thể kiểm tra chi tiết cụ thể, nhưng có thể kiểm tra cấu trúc và tính hợp lý của dữ liệu được trả về (ví dụ nó có tất cả các trường được thiết lập, và là một thời gian trong vòng 5 giây kể từ bây giờ).

Ngoài ra, bạn nên chạy thử nghiệm đơn vị trong môi trường thử nghiệm nơi bạn có toàn quyền kiểm soát những gì được lưu trữ trong cơ sở dữ liệu. Bạn không muốn chạy chúng với dữ liệu sản xuất.

+0

Các điểm tốt. Vì vậy, bạn đang nói rằng chúng ta chỉ nên kiểm tra logic của các hàm truy xuất dữ liệu của chúng tôi, không phải liệu dữ liệu đã truy xuất có đúng không? Ngoài ra, trong môi trường phát triển của chúng tôi, chúng tôi thường thực hiện đồng bộ hóa một chiều của DB trực tiếp -> dev DB để chúng tôi đang làm việc với dữ liệu gần đây. Trong mọi trường hợp, dữ liệu vẫn động. Cảm ơn. –

+0

Ở cấp độ đơn vị, tôi có xu hướng thích kiểm tra rằng logic của tôi cho những gì tôi viết cho db là chính xác, cũng như logic của tôi cho những gì tôi làm với lần đọc của tôi. Tôi không cần phải kiểm tra đơn vị sql đối với cơ sở dữ liệu, trừ khi tôi đang sử dụng một số ORM tùy chỉnh mà tôi đã xây dựng. Sau đó, tôi thường sẽ viết các bài kiểm tra chức năng hoặc tích hợp cho thấy dữ liệu của tôi là những gì tôi mong đợi. Thực hiện những điều này chống lại một db không được cập nhật bởi bất cứ điều gì khác hơn là các bài kiểm tra. Mô phỏng các kịch bản trong thế giới thực với dữ liệu động là tốt để thử nghiệm tích hợp (và hiệu suất), nhưng sự tự tin trong hệ thống phải là từ các hệ thống khác. –

+0

Làm thế nào để bạn thử một chức năng? –

0

Bạn không thể, thực sự. Bạn sẽ cần một bộ dữ liệu tĩnh được bảo đảm để tạo các bài kiểm tra đơn vị đáng tin cậy. Có lẽ ảnh chụp nhanh cơ sở dữ liệu sẽ hoạt động cho bạn.

dữ liệu động có thể hữu ích trong những cách khác, chẳng hạn như để thực hiện kiểm tra hồi quy ...

0

Hầu hết các bài kiểm tra tập trung vào các đường dẫn logic mà có liên quan đến những thứ như thu thập dữ liệu. Không phải về tính hợp lệ của dữ liệu. Hiệu lực của dữ liệu chỉ có ý nghĩa nếu ứng dụng của bạn bằng cách nào đó tính toán hoặc tổng hợp nó hoặc bất cứ điều gì, trong trường hợp đó bạn sẽ có thể kiểm soát đầu vào và xác minh rằng kết quả là chính xác.

Điều đó nói rằng, đôi khi bạn muốn nhấn cùng một cơ sở dữ liệu mà ứng dụng của bạn đang sử dụng để xác minh trả về. Ví dụ: nếu bạn đang thử nghiệm hàm trả về tập dữ liệu được lọc, kiểm tra đơn vị của bạn có thể thực hiện cùng một truy vấn và sau đó thực hiện so sánh từng hàng, ví dụ, mỗi bản ghi khóa chính và xác minh rằng hàm của bạn đã trả về cùng một tập hợp dữ liệu bạn đang mong đợi.

Tôi không biết đây có phải là câu hỏi cụ thể của bạn hay không, nhưng không có gì sai khi nhấn cơ sở dữ liệu để thực hiện các xác nhận trong các bài kiểm tra đơn vị, ngược lại. Ít nhất tôi cũng làm mọi lúc và không ai cố gắng bắt tôi bị bắt :)

0

Bỏ qua thực tế là bạn đang nói về DB Tôi nghĩ rằng bạn có thể đang tìm kiếm các bài kiểm tra đơn vị của bạn để bao gồm mọi sự kiện có thể dẫn đến tập hợp các lợi nhuận giảm dần. Nếu tôi là bạn tôi sẽ bao gồm một con đường tiêu chuẩn và sau đó một vài trường hợp cạnh. Thực tế là bạn không thể kiểm tra thực tế mọi thứ.

Dưới đây là một số đọc thêm

http://37signals.com/svn/posts/3159-testing-like-the-tsa
How deep are your unit tests?
http://johnnosnose.blogspot.co.uk/2012/04/re-over-testing.html
http://martinfowler.com/bliki/TestCoverage.html

Nhìn vào specifc vấn đề liên quan db của bạn, để kiểm tra chức năng này, bạn có thể cần phải tạo ra một seam đến trước poulate dữ liệu vì vậy bạn có thể bao gồm những trường hợp đó.

+0

Heh Theo kinh nghiệm của tôi, hầu hết các lỗi đều xuất hiện chính xác trong các lĩnh vực khó kiểm tra - và do đó có vẻ như đó là những lĩnh vực duy nhất được hưởng lợi từ việc đầu tư thời gian trong một khuôn khổ thử nghiệm. Các nhà quản lý thấy rằng, tôi chắc chắn và nghĩ rằng, "chúng tôi chỉ cần kiểm tra đơn vị nhiều hơn cho x, y z" khi thực tế 'x', 'y' và 'z' về cơ bản được xác định bởi đặc tính gần như không thể kiểm chứng được. Vì những lý do này, tôi xem xét đơn vị thử nghiệm là không linh hoạt hơn so với thực hành OOP dựa trên UML cứng nhắc, không nhanh nhẹn nhất. Là một nhà phát triển solo làm việc mỗi giờ nó thực sự là một công việc cho một viên đạn bạc. –

1

Nếu chức năng của bạn làm điều gì đó thú vị ngoài việc kéo dữ liệu ra khỏi cơ sở dữ liệu, bạn nên trích xuất truy xuất vào một chức năng khác và giả lập nó, để bạn có thể kiểm tra phần còn lại.

Điều này vẫn để lại cho bạn nhiệm vụ kiểm tra quyền truy cập cơ sở dữ liệu. Bạn có thể không thực sự làm một bài kiểm tra đơn vị cho điều đó, bởi vì điều đó sẽ theo định nghĩa không truy cập bất kỳ db nào và bạn chỉ có thể kiểm tra nếu nó gửi câu lệnh sql mà bạn nghĩ, nhưng không phải nếu câu lệnh sql thực sự hoạt động.

Vì vậy, bạn cần có một cơ sở dữ liệu

Bạn có optiones khác nhau:

1) tạo ra một cơ sở dữ liệu cố định cho xét nghiệm như vậy mà không có được thay đổi bởi các cuộc thử nghiệm.

Pro: Khái niệm dễ dàng Con: khó duy trì. Các thử nghiệm trở nên phụ thuộc lẫn nhau, bởi vì chúng dựa vào cùng một dữ liệu. Không có cách nào để kiểm tra nội dung cập nhật, chèn hoặc xóa (hãy để một mình DDL)

2) tạo cơ sở dữ liệu trong khi kiểm tra. Bây giờ bạn có hai vấn đề: thiết lập cơ sở dữ liệu cho thử nghiệm và điền nó với dữ liệu.

Thiết lập:

1) có một máy chủ cơ sở dữ liệu đang chạy, với một người dùng/schema/cơ sở dữ liệu cho erveryone ai cần để chạy thử nghiệm (ít nhất devs + ci-server). Giản đồ có thể được tạo bằng cách sử dụng các công cụ như ngủ đông hoặc các tập lệnh bạn sử dụng để triển khai.

Hoạt động tốt, nhưng làm cho các DBA cũ trở nên điên rồ. Ứng dụng không được phụ thuộc vào tên lược đồ. Bạn cũng sẽ gặp phải vấn đề khi bạn có nhiều hơn một lược đồ được ứng dụng sử dụng. Thiết lập này khá chậm. Nó có thể giúp đỡ để đưa vào đĩa nhanh. Giống như đĩa RAM

2) Có cơ sở dữ liệu trong bộ nhớ. Dễ dàng bắt đầu từ mã và nhanh chóng. Nhưng trong hầu hết các trường hợp, nó sẽ hoạt động giống như cơ sở dữ liệu sản xuất của bạn. Điều này là ít quan tâm nếu bạn sử dụng một cái gì đó mà cố gắng để che giấu sự khác biệt. Tôi thường sử dụng một cơ sở dữ liệu bộ nhớ cho giai đoạn xây dựng đầu tiên và điều thực sự trong giai đoạn thứ hai.

Loading the TestData

1) người bảo tôi dùng DBUnit. Tôi không tin rằng nó có vẻ là rất nhiều XML và khó để duy trì khi cột hoặc ràng buộc thay đổi.

2) Tôi thích mã ứng dụng thông thường hơn. (Java + Hibernate) trong trường hợp của tôi, nhưng mã viết dữ liệu của bạn vào cơ sở dữ liệu trong sản xuất nên trong nhiều trường hợp phù hợp để viết dữ liệu thử nghiệm cho thử nghiệm của bạn. Nó giúp có một API đặc biệt nhỏ che giấu các chi tiết đáp ứng tất cả khóa và nội dung ngoài: http://blog.schauderhaft.de/2011/03/13/testing-databases-with-junit-and-hibernate-part-1-one-to-rule-them/

0

Tôi sẽ tạo dữ liệu trong bản thân kiểm tra. Bằng cách đó bạn thậm chí có thể kiểm tra các kịch bản phức tạp cho dữ liệu luôn thay đổi. Điểm mấu chốt là bạn có thể kiểm soát các thay đổi dữ liệu trong các thử nghiệm của mình bằng cách có một db thử nghiệm chuyên dụng,

Bước 1: Chèn dữ liệu bạn cần vào một db chỉ được sử dụng bởi kiểm tra Bước 2: db là hiện đang ở trạng thái có thể dự đoán ổn định, vì vậy, bạn có thể chạy truy vấn của mình và kiểm tra đầu ra

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