2010-10-19 41 views
5

Sau nhiều tháng thất vọng và dành thời gian để chèn kim trong búp bê voodoo của các nhà phát triển trước, tôi quyết định cố gắng tái cấu trúc mã cũ hơn.UnitTesting một lớp học trả về một tập dữ liệu phức tạp

Tôi đã đặt hàng Micheal Feather's book, tôi vào Fowler's refactoring và tôi đã thực hiện một số dự án mẫu với DUnit.

Vì vậy, ngay cả khi tôi không nắm vững chủ đề, tôi cảm thấy đã đến lúc hành động và đưa một số ý tưởng vào thực tế.

Gần như 100% mã tôi làm việc có logic nghiệp vụ bị mắc kẹt trong giao diện người dùng, hơn nữa tất cả là lập trình thủ tục (với một vài ngoại lệ). Ứng dụng bắt đầu nhanh như & bẩn và tiếp tục như vậy.

Bây giờ viết các bài kiểm tra cho tất cả các ứng dụng là một nhiệm vụ vô nghĩa trong trường hợp của tôi, nhưng tôi muốn cố gắng unittest một cái gì đó mà tôi cần phải refactor.

Một trong những nhiệm vụ phức tạp mà một "lớp logic kinh doanh TForm" lớn thực hiện là đọc dữ liệu DB, thực hiện một số tính toán và điền vào một thành phần lập lịch biểu. Tôi muốn loại bỏ dữ liệu đọc DB và phần tính toán và gán cho một lớp mới nhiệm vụ này. Tất nhiên đây là một cách để cải thiện thiết kế hiện tại, nó không phải là cách tốt nhất để bắt đầu từ đầu, nhưng tôi muốn làm điều này vì dữ liệu được trả về bởi lớp mới này cũng hữu ích theo những cách khác, ví dụ bây giờ tôi đã được yêu cầu gửi thông báo e-mail của dữ liệu lịch biểu.

Vì vậy, để tránh thao tác sao chép và dán lớn, tôi cần lớp mới.

Bây giờ trình lên lịch được điền từ tập dữ liệu khổng lồ (kích thước lớn và số trường), có thể bước tái cấu trúc đầu tiên có thể lấy tập dữ liệu từ lớp mới. Nhưng sau đó trong tương lai tôi nên sử dụng một lớp mới (như TSchedulerData hoặc một số tên khác ít ràng buộc để lên lịch) để quản lý dữ liệu, và thay vì có một tập dữ liệu như là kết quả tôi có thể có một đối tượng TSchedulerData.

Kể từ khi trình tái cấu trúc xảy ra ở các bước nhỏ và cần thử nghiệm để cấu trúc lại tốt hơn, tôi hơi bối rối về cách tiến hành.

Các điểm sau không rõ ràng đối với tôi:

1) cách kiểm tra tập dữ liệu phức tạp? Tôi có nên chạy ứng dụng đang hoạt động, lưu một tập kết quả thành xml và viết một bài kiểm tra nơi tôi sử dụng một TClientDataSet chứa dữ liệu xml đó không?

2) Tôi phải quan tâm đến TSchedulerData bao nhiêu? Tôi có nghĩa là tôi không chắc chắn 100% tôi sẽ sử dụng TSchedulerData, có thể tôi sẽ gắn bó với Dataset, dù sao thì nghĩ đến việc tạo ra các thử nghiệm phức tạp sẽ bị loại bỏ trong 2 tuần không hấp dẫn đối với DUnitNewbee. Dù sao có lẽ đây là cách nó hoạt động. Tôi không thể tưởng tượng số lượng lỗi mà tôi sẽ phải đối mặt mà không có một thử nghiệm.

Lưu ý cuối cùng: Tôi biết ai đó nghĩ rằng viết lại từ đầu là một lựa chọn tốt hơn, nhưng đây không phải là một lựa chọn. "Ứng dụng là rất lớn và nó được bán ngày hôm nay và các tính năng mới được yêu cầu ngày hôm nay không để có được ra khỏi kinh doanh". Đây là những gì tôi đã được nói, dù sao việc tái cấu trúc có thể cứu mạng tôi và kéo dài tuổi thọ của ứng dụng.

Trả lời

2

Mục tiêu cuối cùng của bạn là tách biệt giao diện người dùng, lưu trữ dữ liệu và logic nghiệp vụ thành các lớp riêng biệt.

Rất khó để kiểm tra giao diện người dùng với khung kiểm tra tự động. Bạn sẽ muốn cuối cùng tách biệt nhiều logic nghiệp vụ khỏi giao diện người dùng nhất có thể. Điều này có thể được thực hiện bằng cách sử dụng một trong các mẫu Model/View/* khác nhau. Tôi thích MVP thụ động xem, mà cố gắng để làm cho giao diện người dùng không có gì nhiều hơn một giao diện. Nếu bạn đang sử dụng Bộ điều khiển giám sát MVP Dataset có thể phù hợp hơn.

Lưu trữ dữ liệu cần có bộ kiểm tra riêng nhưng các thử nghiệm này khác với các bài kiểm tra đơn vị (mặc dù bạn có thể sử dụng cùng một khung kiểm tra đơn vị) và thường có ít hơn. Bạn có thể thoát khỏi điều này vì hầu hết việc nâng hạng nặng đang được thực hiện bởi các thành phần dữ liệu của bên thứ ba và một dbms (trong trường hợp của bạn là T * Dataset). Đây là những bài kiểm tra tích hợp. Về cơ bản, đảm bảo mã của bạn phát đẹp với mã của nhà cung cấp. Cũng cần thiết nếu bạn có bất kỳ thủ tục được lưu trữ được xác định trong DB. Chúng chậm hơn nhiều so với các bài kiểm tra đơn vị và không cần phải chạy thường xuyên.

Logic nghiệp vụ là những gì bạn muốn thử nghiệm nhiều nhất. Mỗi phép tính, vòng lặp hoặc chi nhánh phải có ít nhất một thử nghiệm (thích hợp hơn). Trong mã kế thừa, logic này thường chạm trực tiếp vào giao diện người dùng và db và thực hiện nhiều việc trong một hàm duy nhất. Ở đây Phương thức trích xuất là bạn của bạn. nơi tốt để trích xuất các phương pháp là:

for I:=0 to List.Count - 1 do 
begin 
    //HERE 
end; 

if /*HERE if its a complex condition*/ then 
begin 
    //HERE 
end 
else 
begin 
    //HERE 
end 

Answer := Var1/Var2 + Var1 * Var3; //HERE 

Khi bạn gặp một trong những điểm khai thác

  1. Quyết định những gì bạn muốn chữ ký phương pháp để trông giống như cho mới phương pháp của bạn: Tên Method, thông số, lợi nhuận giá trị.
  2. Viết thử nghiệm gọi nó và kiểm tra kết quả mong đợi.
  3. Trích xuất phương thức.

Nếu mọi việc suôn sẻ, bạn sẽ có phương pháp mới được trích xuất với ít nhất một lần kiểm tra đơn vị truyền qua.

Delphi được xây dựng trong Phương thức trích xuất không cung cấp cho bạn bất kỳ cách nào để điều chỉnh chữ ký vì vậy nếu đó là tùy chọn của riêng bạn, bạn sẽ phải thực hiện và sửa lỗi sau khi trích xuất. Bạn cũng sẽ muốn đặt phương thức mới ở chế độ công khai để thử nghiệm của bạn có thể truy cập nó. Một số người balk làm cho một phương pháp tiện ích tư nhân công khai nhưng ở giai đoạn đầu này bạn có rất ít sự lựa chọn. Khi bạn đã thực hiện đủ tiến bộ, bạn sẽ bắt đầu thấy rằng một số phương thức tiện ích mà bạn đã trích xuất thuộc về lớp riêng của chúng (trong trường hợp này chúng phải được công khai) trong khi các phương thức khác có thể được thực hiện riêng tư/được bảo vệ và kiểm tra gián tiếp bằng cách thử nghiệm các phương pháp phụ thuộc vào chúng.

Khi bộ thử nghiệm của bạn phát triển, bạn sẽ muốn chạy chúng sau mỗi thay đổi để đảm bảo thay đổi mới nhất của bạn không bị hỏng ở nơi khác.

Chủ đề này quá lớn để bao gồm hoàn toàn trong câu trả lời. Bạn sẽ thấy phần lớn các câu hỏi của bạn được đề cập khi cuốn sách đó đến.

2

Tôi muốn nói cách tiếp cận nó trong các bước bé tập trung.

BướC# 1: Luôn luôn là để có được một số xét nghiệm xung quanh khu vực của bạn xâm lược TForm - kiểm tra hồi quy aka mạng lưới an toàn. Trong trường hợp của bạn, hãy hiểu ứng dụng đang làm gì. Từ những gì tôi đọc, nó có vẻ là một máy biến áp dữ liệu.Vì vậy, dành thời gian để hiểu tất cả (hoặc quan trọng nhất nếu tất cả là không khả thi) sự kết hợp của dữ liệu đầu vào và lịch trình đầu ra tương ứng. Viết chúng lên làm bài kiểm tra. Đảm bảo rằng tất cả các bài kiểm tra đều vượt qua.

BướC# 2: Bây giờ thử tái cấu trúc lại. Di chuyển các khối mã vào các lớp kết dính, v.v. dưới sự an toàn của mạng hồi quy.

Kiểm tra tập dữ liệu phức tạp - bãi tệp thử nghiệm phải là phương sách cuối cùng. Nhưng trong trường hợp này, nó có vẻ như là một lựa chọn đơn giản để bắt đầu. Có lẽ sau này bạn có thể biến nó thành đối tượng miền đầu tiên TSchedule với việc thực hiện Equals() của riêng nó. Trì hoãn các quyết định/thay đổi thiết kế cho đến khi bạn có một bộ kiểm tra hồi quy vững chắc xung quanh khu vực sửa đổi của bạn.

+0

Ok cảm ơn. Nỗi sợ hãi mà tôi có là các bài kiểm tra viết sẽ mất rất nhiều thời gian, bởi vì dữ liệu phức tạp. File dumps rất phức tạp, do đó, đây là lần đầu tiên tôi thực hiện cuộc sống không thực hiện được, tôi sợ mất một tuần và kết thúc với các bài kiểm tra không thành công. Dù sao tôi không có nơi nào khác để bắt đầu, ý tôi là, tôi cần phải thay đổi MÃ NÀY và vì vậy tôi nên bắt đầu từ đây. – LaBracca

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