Chúng ta nên phòng thủ như thế nào?


11

Chúng tôi đã chạy Pex qua một số mã, và nó đã cho thấy một số điều tốt (cũng là những điều xấu, nhưng hiển thị chúng trước khi nó được đưa vào sản xuất!).

Tuy nhiên, một trong những điều tốt đẹp về Pex là nó không nhất thiết phải ngừng cố gắng tìm kiếm các vấn đề.

Một lĩnh vực chúng tôi tìm thấy là khi đi qua một chuỗi, chúng tôi không kiểm tra các chuỗi trống.

Vì vậy, chúng tôi đã thay đổi:

if (inputString == null)

đến

if (string.IsNullOrEmpty(inputString)) // ***

Điều đó đã khắc phục các vấn đề ban đầu. Nhưng sau đó, khi chúng tôi chạy lại Pex, nó đã quyết định rằng:

inputString = "\0";

đã gây ra vấn đề. Và sau đó

inputString = "\u0001";

Những gì chúng tôi đã quyết định là mặc định có thể được sử dụng nếu chúng tôi gặp phải // ***và chúng tôi rất vui khi thấy ngoại lệ gây ra bởi bất kỳ đầu vào kỳ quặc nào khác (và xử lý nó).

Như thế đủ chưa?


Bạn đã kiểm tra xem liệu bạn có thể tắt một số cảnh báo không? Tôi biết JTest cũng sẽ làm điều đó, nhưng đó cũng là một lựa chọn để tắt một số khuyến nghị của nó. Phải mất một thời gian với việc điều chỉnh các cài đặt để có được một hồ sơ kiểm tra mã mà chúng tôi thích.
Thất vọngWithFormsDesigner

@Frustrated: Vâng, chắc chắn có những điều chỉnh cho hồ sơ chúng ta có thể làm và đang làm. Pex là một công cụ tuyệt vời. Kết quả nó cho thấy chỉ khiến câu hỏi.
Peter K.

Tôi không có câu trả lời cho bạn, nhưng tôi muốn nói lời cảm ơn vì liên kết đó đến điều Pex này; nó trông khá gọn gàng nếu đó là những gì tôi nghĩ và sẽ tự động (?) tạo ra các thử nghiệm đơn vị cho mã hiện có. Mã tôi đang làm việc rất lớn và không có thử nghiệm và mã được ghép rất chặt chẽ nên không thể cấu trúc lại bất cứ thứ gì.
Wayne Molina

@WayneM: Vâng, nó khá tốt, mặc dù tôi cần trải qua một vài ví dụ để hiểu những gì nó đang làm. Đối với mã kế thừa, nó thật tuyệt. Nó thậm chí còn tốt hơn cho mã mới!
Peter K.

Câu trả lời:


9

Ba câu hỏi sẽ giúp bạn xác định mức độ phòng thủ trong mã hóa của bạn.

Đầu tiên - Hậu quả của việc nhập liệu xấu là gì? Nếu đó là một thông báo lỗi trên một trong các PC của nhà phát triển của bạn, có lẽ không quá quan trọng để phòng thủ. Nó có thể dẫn đến sự gián đoạn tài chính tại khách hàng, sự gián đoạn thông tin kế toán IE? Đây có phải là một hệ thống thời gian thực, nơi cuộc sống có nguy cơ? Trong kịch bản sống / chết, có lẽ nên có nhiều mã xác thực và xử lý lỗi hơn mã tính năng thực tế.

Thứ hai, có bao nhiêu người sẽ sử dụng lại chức năng hoặc đoạn mã này? Chỉ có bạn? Bộ phận của bạn? Công ty của bạn? Khách hàng của bạn? Việc sử dụng mã càng rộng thì càng phòng thủ.

Thứ ba - nguồn đầu vào mà tôi đang xác nhận là gì? Nếu đó là đầu vào từ người dùng hoặc từ một trang web công cộng, tôi sẽ siêu phòng thủ. Nếu đầu vào luôn đến từ mã của bạn, hãy phòng thủ một chút, nhưng đừng dành thời gian quá hạn để kiểm tra.

Sẽ luôn có thể thêm vào kiểm tra lỗi và xác nhận lỗi trong một hệ thống. Vấn đề là chi phí viết và duy trì mã này lớn hơn chi phí cho các vấn đề gây ra bởi lỗi trong mã.


6

Người dùng là xấu, và bất cứ điều gì họ nhập vào nên được kiểm tra với sự nghiêm ngặt tối đa.

Bất cứ điều gì được tạo ra mà không có lợi ích của đầu vào của người dùng, hoặc từ dữ liệu được khử trùng trước, không cần phải được kiểm tra ở cùng cấp độ. Vấn đề ở đây là khi bạn quên và sử dụng các phương pháp này trên dữ liệu xấu, bởi vì bạn đã quên rằng mã không bị cứng.

Một điều bạn nên luôn luôn kiểm tra là bất cứ điều gì có thể gây ra tràn hoặc sụp đổ. Không quan trọng phương pháp đó được chôn sâu đến mức nào, và bạn chắc chắn rằng tình trạng đó không bao giờ có thể xảy ra. Dù sao thì bạn cũng cần lập trình cho nó, chỉ để xoa dịu Murphy.


2

Tôi sẽ phòng thủ như bạn cần phải được. Một chút mơ hồ, tôi đoán vậy nhưng tôi sẽ cố gắng giải thích.

Khi bạn đúng một phương thức, nếu phương thức đó có các tham số đầu vào, bạn phải đưa ra quyết định về những gì bạn mong đợi các tham số đó. Trong các tình huống và địa điểm trong một ứng dụng, điều này sẽ khác nhau. Ví dụ: nếu một phương thức hoặc một đoạn mã đang chấp nhận dữ liệu từ đầu vào của người dùng thì bạn sẽ muốn bao gồm tất cả các cơ sở mã và xử lý bất kỳ đầu vào nào phù hợp cho dù thông qua một thông báo lỗi hoặc một cách hiển thị dữ liệu không thể chấp nhận được.

Nếu phương thức là một API tiếp xúc. Bạn không thể kiểm soát những gì đang đến vì vậy bạn nên thử và bao gồm tất cả các khía cạnh và chương trình phù hợp.

Đối với các phương thức được sản xuất trong công cụ cốt lõi của dự án của bạn, ở đây bạn có quyết định đưa ra. Tôi có cho rằng dữ liệu đến đã được sàng lọc trước và xác thực trước khi đến hay tôi nên đưa vào các kiểm tra cần thiết. Tôi đoán điều này phụ thuộc vào mức độ khái niệm của phương pháp và nếu đây là nơi chấp nhận được để kiểm tra. Vì vậy, những điều tôi có thể xem xét là:

1) Đây có phải là nơi duy nhất tôi cần thực hiện kiểm tra này không? Biến này có cần được kiểm tra ở nhiều nơi khác nhau cho tình trạng này không. Nếu vậy tôi có thể thực hiện kiểm tra một lần cao hơn chuỗi và sau đó giả sử tính hợp lệ

2) Các thành phần khác của hệ thống dự kiến ​​sẽ hoạt động với các phương thức và giao diện tôi viết. Nếu vậy, bạn có thể kiểm soát thông qua các câu lệnh xác nhận gỡ lỗi, gỡ lỗi ngoại lệ, nhận xét phương thức và kiến ​​trúc hệ thống chung về kết quả bạn yêu cầu hoặc dữ liệu cần kiểm tra được đưa ra.

3) Kết quả của sự thất bại tại thời điểm này trong mã. Nó sẽ gây ra toàn bộ điều thất bại? Bất kỳ lỗi nào sẽ được bắt ở nơi khác và ít nhất lỗi đó sẽ bị bắt.

4) Có ý nghĩa gì khi đặt một kiểm tra ở đây? Đôi khi, kiểm tra một phần dữ liệu bị hỏng có thể mặc dù giúp giải quyết vấn đề tại thời điểm đó và không xảy ra lỗi có thể giúp che giấu nó. Tại thời điểm đó, bạn có thể mất hàng giờ để theo dõi một vấn đề khác chỉ để tìm ra vấn đề thực sự là do kiểm tra dữ liệu hợp lệ trong chuỗi sự kiện xảy ra với người dùng / nhà phát triển đã được báo cáo.

Nói chung, tôi là một lập trình viên phòng thủ, tuy nhiên tôi cũng tin rằng với TDD kỹ lưỡng và kiểm tra đơn vị, bạn có thể kiểm tra mã ở các cấp độ yêu cầu và tự tin rằng nó hoạt động như bình thường khi đến bất kỳ phần cấp thấp nào .


1

Tôi đã dành nhiều tuần trước cho các lỗi có thể được phát hiện với 5 phút làm thêm như thế này. Trong tâm trí của tôi, công việc này luôn luôn có giá trị. Bạn sẽ sửa lỗi cuối cùng. Câu hỏi duy nhất là bạn sẽ mất bao lâu.

Một điều mà các loại công cụ phân tích này thường phát hiện ra là những thứ không nhất thiết là lỗi, nhưng là thói quen lập trình xấu khiến lỗi dễ xảy ra hơn. Một thói quen phổ biến như vậy là khởi tạo biến. Đôi khi một chuỗi rỗng là một giá trị hoàn toàn hợp lệ cho một biến. Trong trường hợp đó, bạn muốn định cấu hình công cụ của mình để không xem đó là lỗi trong trường hợp cụ thể đó. Tuy nhiên, thường thì một chuỗi rỗng không phải là giá trị hợp lệ cho một biến, nhưng mọi người vẫn cài đặt nó bởi vì trình biên dịch phàn nàn nếu không có trong đó hoặc ngôn ngữ của bạn sẽ tự động khởi tạo chuỗi trống cho dù đó có hợp lệ hay không.

Điều này làm mọi người thất vọng vì có vẻ như một cái bẫy 22 không có giải pháp hợp lệ, nhưng giải pháp là để cấu trúc lại mã của bạn để nó không cần phải khởi tạo biến cho đến khi có một giá trị hợp lệ để đặt vào đó. Điều đó đòi hỏi một số suy nghĩ thêm trước, nhưng làm cho mã của bạn mạnh mẽ hơn nhiều, và thực sự dễ viết và duy trì lâu dài hơn.

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.