unit-testing - true - scalatest tutorial
Comparar los contenidos de la colección con ScalaTest (2)
Estoy intentando probar algunos Scala que son muy pesados. Estas colecciones se devuelven como Iterable[T]
, por lo que estoy interesado en el contenido de la colección, incluso si los tipos subyacentes son diferentes. Esto es en realidad dos problemas relacionados:
- ¿Cómo afirmo que dos colecciones ordenadas contienen la misma secuencia de elementos?
- ¿Cómo afirmo que dos colecciones desordenadas contienen el mismo conjunto de elementos?
En resumen, estoy buscando el equivalente en Scala de CollectionAssert.AreEqual
de NUnit (ordenado) y CollectionAssert.AreEquivalent
(desordenado) en ScalaTest:
Set(1, 2) should equal (List(1, 2)) // ordered, pass
Iterable(2, 1) should equal (Iterable(1, 2)) // unordered, pass
Puede probar .toSeq
para las colecciones ordenadas y .toSet
para desordenado, que captura lo que quiere hasta donde yo lo entiendo.
Los siguientes pases:
class Temp extends FunSuite with ShouldMatchers {
test("1") { Array(1, 2).toSeq should equal (List(1, 2).toSeq) }
test("2") { Array(2, 1).toSeq should not equal (List(1, 2).toSeq) }
test("2b") { Array(2, 1) should not equal (List(1, 2)) }
test("3") { Iterable(2, 1).toSet should equal (Iterable(1, 2).toSet) }
test("4") { Iterable(2, 1) should not equal (Iterable(1, 2)) }
}
Por cierto, un Set
no está ordenado.
editar: para evitar eliminar elementos duplicados, intente toSeq.sorted
. El siguiente pase:
test("5") { Iterable(2, 1).toSeq.sorted should equal (Iterable(1, 2).toSeq.sorted) }
test("6") { Iterable(2, 1).toSeq should not equal (Iterable(1, 2).toSeq) }
edición 2: para las colecciones desordenadas donde los elementos no pueden ser ordenados, puede usar este método:
def sameAs[A](c: Traversable[A], d: Traversable[A]): Boolean =
if (c.isEmpty) d.isEmpty
else {
val (e, f) = d span (c.head !=)
if (f.isEmpty) false else sameAs(c.tail, e ++ f.tail)
}
ej. (tenga en cuenta el uso de símbolos ''a ''b ''c
que no tienen un orden definido)
test("7") { assert( sameAs(Iterable(2, 1), Iterable(1, 2) )) }
test("8") { assert( sameAs(Array(''a, ''c, ''b), List(''c, ''a, ''b) )) }
test("9") { assert( sameAs("cba", Set(''a'', ''b'', ''c'') )) }
sameAs
alternativa de sameAs
:
def sameAs[A](c: Traversable[A], d: Traversable[A]) = {
def counts(e: Traversable[A]) = e groupBy identity mapValues (_.size)
counts(c) == counts(d)
}
Mientras tanto puedes usar
Iterable(2, 1) should contain theSameElementsAs Iterable(1, 2)
Para probar el conjunto ordenado, debe convertirlo a una secuencia.
Set(1, 2).toSeq should contain theSameElementsInOrderAs List(1, 2)