我的任務是爲大量度量數據結構(即quadtree和k-d tree變體)創建實現。我已經完成了大約四個這樣的實現,但我目前測試的方式並不是,因爲我沒有更好的詞彙,所以不錯。單元測試數據結構的內部狀態
我需要一種乾淨的方式來測試從這些樹/ trie結構中插入和刪除數據的方式,以便我可以測試節點的內部結構(檢查父母,子女,排序等)。這些實現遵循單獨的正確性證明和運行時分析,所以我需要確保不僅正確插入節點(意味着可以從樹中稍後檢索),還要確保樹中的「正確」位置。
然而,「單元測試」似乎是錯誤的方法,因爲如果我沒有弄錯,它的目的是測試一個結構或系統的外部API。我見過很多單元測試相關的問題,問我「如何在單元測試中訪問私有域」或「如何測試非公共方法的返回值」,答案通常是「不」 t「 - 我同意這個答案。
所以我不會讓任何人願意幫助只是含糊的隨筆,我的樹實現該接口是以下(基於關閉Java集合的地圖界面):
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的技術,而不覺得我在摧毀美麗的認知邊界)?
只要我的正確性證明實際上是正確的,節點排序的內部狀態應該永遠不會改變;) – efritz
正確但是如果變量名稱改變,例如測試可能會中斷。這更像是一個白盒單元測試(與黑盒相對)。有時這種風格是適當的,聽起來就像你的情況,這是你在找什麼。 –