Tengo la tarea de crear implementaciones para un gran número de estructuras de datos de métricas (concretamente quadtree y k-d tree variantes). Tengo aproximadamente cuatro de estas implementaciones inactivas, pero la forma en que estoy actualmente probando no es, por mi falta de una mejor palabra, buena.Prueba de unidad Estado interno de la estructura de datos
Necesito una forma limpia de probar la inserción y eliminación de datos de estas estructuras de árbol/trie de forma que pueda probar las estructuras internas de los nodos (verificar padres, hijos, ordenar, etc.). Estas implementaciones siguen pruebas de corrección y análisis de tiempo de ejecución por separado, así que necesito asegurarme de que no solo se inserta un nodo correctamente (es decir, recuperable del árbol más adelante), sino también en una posición muy "correcta" en el árbol.
"Pruebas unitarias" parece ser la forma incorrecta de hacerlo, sin embargo, ya que su propósito, si no me equivoco, es probar una estructura o API externa del sistema. He visto muchas preguntas relacionadas con las pruebas unitarias que preguntaban "¿cómo obtengo acceso a un campo privado en la prueba de unidad" o "cómo pruebo los valores de devolución de un método no público?", Y la respuesta generalmente es "no" t "- y estoy de acuerdo con esta respuesta.
Y por lo que no deja a nadie dispuesto a ayudar con divagaciones simplemente vagos, la interfaz de mis árboles implementan es la siguiente (con sede fuera interfaz de mapa de la colección de 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();
}
Esto hace que sea difícil Pruebe con solo los métodos públicos, ya que necesito ciertos datos (punteros para niños/padres) que no están disponibles en la interfaz pública. Además, en las estructuras trie (PR Quadtree, PRKDTree, variantes de MX, etc.) tengo nodos que están separados de los datos, por lo que la creación de un método público que devuelva un "nodo" también se abstraerá demasiado para obtener los datos correctos.
¿Qué tipo de método de prueba (o técnicas que podría usar con JUnit y no siento que estoy destruyendo hermosos límites cognitivos) estoy buscando?
El estado interno en cuanto a ordenamientos de nodos nunca debe cambiar, siempre que mis pruebas de corrección sean realmente correctas;) – efritz
Correcto, pero si cambian los nombres de las variables, por ejemplo, la prueba puede romperse. Esto es más una prueba de unidad de whitebox (a diferencia de blackbox).Algunas veces este estilo es apropiado, y suena como en tu caso, es lo que estás buscando. –