私には、多数のメトリックデータ構造(つまり、クアッドツリーとkdツリーのバリアント)の実装を作成するタスクがあります。私はこれらの実装のうち約4つをダウンさせましたが、現在テストしている方法は、より良い言葉がないため、良いものではありません。
ノードの内部構造をテストできるように(親、子、順序などをチェックする)、これらのツリー/トライ構造からのデータの挿入と削除をテストするクリーンな方法が必要です。これらの実装は、個別の正確性の証明と実行時分析に従っているため、ノードが正しく挿入されている(つまり、後でツリーから取得できる)だけでなく、ツリー内の非常に「正しい」位置にあることを確認する必要があります。
「ユニットテスト」はこれを行うのに間違った方法のように思えますが、それは私が間違っていなければ、構造またはシステムの外部APIをテストすることが目的であるためです。「ユニットテストでプライベートフィールドにアクセスするにはどうすればよいですか」または「非公開メソッドの戻り値をテストするにはどうすればよいですか」というユニットテスト関連の質問をたくさん見ましたが、答えは一般的に「しない」です。 t"-そして私はこの答えに同意します。
ですから、漠然としたとりとめのないことを喜んで手伝ってくれる人を残さないので、私のツリーが実装するインターフェースは次のとおりです(JavaコレクションのMapインターフェースに基づく):
public interface SpatialMap<K, V> extends Iterable<SpatialMap.Entry<K, V>>
{
// Query Operations
/**
* Returns the number of key-value mappings in this map. If the map contains more than
* <tt>Integer.MAX_VALUE</tt> elements, returns <tt>Integer.MAX_VALUE</tt>.
*
* @return The number of key-value mappings in this map.
*/
int size();
/**
* Returns <tt>true</tt> if this map contains no key-value mappings.
*
* @return <tt>true</tt> if this map contains no key-value mappings.
*/
boolean isEmpty();
/**
* Returns <tt>true</tt> if this map contains a mapping for the specified key.
*
* @param key
* The key whose presence in this map is to be tested.
* @return <tt>true</tt> if this map contains a mapping for the specified key.
*/
boolean containsKey(K key);
/**
* Returns the value to which the specified key is mapped, or {@code null} if this map contains
* no mapping for the key.
*
* <p>A return value of {@code null} does not <i>necessarily</i> indicate that the map contains
* no mapping for the key; it's also possible that the map explicitly maps the key to
* {@code null}. The {@link #containsKey containsKey} operation may be used to distinguish these
* two cases.
*
* @see #put(Comparable, Comparable, Object)
*
* @param key
* The key whose associated value is to be returned.
* @return The value to which the specified key is mapped, or {@code null} if this map contains
* no mapping for the key.
*/
V get(K key);
// Modification Operations
/**
* Associates the specified value with the specified key in this map. If the map previously
* contained a mapping for the key, the old value is replaced.
*
* @param key
* The key with which the specified value is to be associated.
* @param data
* The value to be associated with the specified key.
* @return The previous value associated with the key, or <tt>null</tt> if there was no mapping
* for the key. (A <tt>null</tt> return can also indicate that the map previously
* associated <tt>null</tt> with <tt>key</tt>.)
*/
V put(K key, V data);
/**
* Removes the mapping for the specified key from this map if present.
*
* @param key
* The key whose mapping is to be removed from the map.
* @return The previous value associated with the key, or <tt>null</tt> if there was no mapping
* for the key. (A <tt>null</tt> return can also indicate that the map previously
* associated <tt>null</tt> with <tt>key</tt>.)
*/
V remove(K key);
// Bulk Operations
/**
* Removes all of the mappings from this map. The map will be empty after this call returns.
*/
void clear();
}
これにより、パブリックインターフェイスから利用できない特定のデータ(子/親ポインター)が必要になるため、パブリックメソッドのみでテストすることは困難になります。また、トライ構造(PR Quadtree、PRKDTree、MXバリアントなど)にはデータから分離されたノードがあるため、「ノード」を返すパブリックメソッドの作成も抽象化されすぎて、正しいデータを取得できません。
どのような種類のテスト方法(またはJUnitで使用でき、美しい認知境界を破壊しているようには感じられない手法)を探していますか?