Unit Testing a large method

后端 未结 5 1543
说谎
说谎 2020-12-18 01:36

Following Test-Driven Development that is.

I\'ve recently implemented a algorithm (A*) that required a clean interface. By clean all I want is a couple of propertie

5条回答
  •  一整个雨季
    2020-12-18 01:38

    I'm assuming that A* means the search algorithm (e.g. http://en.wikipedia.org/wiki/A*_search_algorithm). If so, I understand your problem as we have similar requirements. Here's the WP algorithm, and I'll comment below:


    Pseudo code

     function A*(start,goal)
         closedset := the empty set                 % The set of nodes already evaluated.     
         openset := set containing the initial node % The set of tentative nodes to be evaluated.
         g_score[start] := 0                        % Distance from start along optimal path.
         h_score[start] := heuristic_estimate_of_distance(start, goal)
         f_score[start] := h_score[start]           % Estimated total distance from start to goal through y.
         while openset is not empty
             x := the node in openset having the lowest f_score[] value
             if x = goal
                 return reconstruct_path(came_from,goal)
             remove x from openset
             add x to closedset
             foreach y in neighbor_nodes(x)
                 if y in closedset
                     continue
                 tentative_g_score := g_score[x] + dist_between(x,y)
    
                 if y not in openset
                     add y to openset
    
                     tentative_is_better := true
                 elseif tentative_g_score < g_score[y]
                     tentative_is_better := true
                 else
                     tentative_is_better := false
                 if tentative_is_better = true
                     came_from[y] := x
                     g_score[y] := tentative_g_score
                     h_score[y] := heuristic_estimate_of_distance(y, goal)
                     f_score[y] := g_score[y] + h_score[y]
         return failure
    
     function reconstruct_path(came_from,current_node)
         if came_from[current_node] is set
             p = reconstruct_path(came_from,came_from[current_node])
             return (p + current_node)
         else
             return the empty path
    

    The closed set can be omitted (yielding a tree search algorithm) if a solution is guaranteed to exist, or if the algorithm is adapted so that new nodes are added to the open set only if they have a lower f value than at any previous iteration.


    First, and I'm not being frivolous, it depends whether you understand the algorithm - it sounds as if you do. It would also be possible to transcribe the algorithm above - hoping it worked) and give it a number of tests. That's what I would do as I suspect that the authors of WP are better than me!. The large-scale tests would exercise edge cases such as no node, one node, two nodes+no edge, etc... If they all passed I would sleep happy. But if they failed there is no choice but to understand the algorithm.

    If so I think you have to construct tests for the data structures. These are (at least) set, distance, score, etc. You have to create these objects and test them. What is the expected distance for case 1,2,3... write tests. What is the effect of adding A to set Z? needs a test. For this algorithm you need to test heuristic_estimate_of_distance and so on. It's a lot of work.

    One approach may be to find an implementation in another language and interrogate it to find the values in the data structures. Of course if you are modifying the algorithm you are on your own!

    There's one thing even worse than this - numerical algorithms. Diagonalizing matrices - do we actually get the right answers. I worked with one scientist writing 3rd derivative matrices - it would terrify me...

提交回复
热议问题