Ktoś wie o dobrej drodze do jednostki testowej Scala aktorzy? W ogólnym sensie mam aktora, który odbiera wiadomość i wysyła w odpowiedzi inne wiadomości. Odbywa się to na wielu wątkach, a aktor, który nie jest poprawny, może albo wysłać złe wiadomości, albo nie wysłać żadnego komunikatu. Potrzebuję prostego sposobu na stworzenie makiety aktora, który wysyła i odbiera wiadomości do testowanego aktora. Jakieś doświadczenia w tej dziedzinie?Jednostki testujące aktorów scala
Odpowiedz
Ze względu na dynamiczny charakter przekazu w stylu aktorskim, kpiny z aktorów zwykle nie stanowią problemu. Po prostu stwórz aktora, który odbiera pożądaną wiadomość i jesteś w domu wolny. Oczywiście musisz upewnić się, że ten fałszywy aktor jest tym, któremu przekazywane są wiadomości, ale to nie powinno stanowić problemu, o ile aktor, który próbujesz przetestować, jest reentrant.
myślę złożoność zależy od czynników paru ...
- Jak Stateful jest aktorem?
Jeśli zachowuje się jak funkcja idempotent, tylko asynchroniczna, to powinna być prosta sprawa kpienia z aktora, który wysyła wiadomość, a następnie sprawdza, czy odbiera oczekiwane komunikaty. Prawdopodobnie chcesz użyć elementu reaguj/odbierz na symulowanym aktorze, na wypadek gdyby w rozsądnym czasie nastąpiła reakcja, zamiast zawieszasz.
Jeśli jednak wiadomości nie są od siebie niezależne, należy przetestować je za pomocą różnych sekwencji komunikatów i oczekiwanych wyników.
- Ile aktorów będzie testowanych przez aktorów?
Jeśli od aktora oczekuje się interakcji z wieloma innymi osobami i jest to stanowy, należy przetestować go z kilkoma aktorami wysyłającymi/odbierającymi wiadomości. Ponieważ prawdopodobnie nie masz żadnej gwarancji na kolejność, w której pojawią się wiadomości, powinieneś być pewien, że albo permutujesz rozkazy, w których aktorzy wysyłają wiadomości, albo wprowadzają losowe pauzy u aktorów generujących komunikaty i przeprowadzają test wiele razy.
Nie znam się na żadnych gotowych frameworkach do testowania aktorów, ale można się też spodziewać inspiracji dla Erlang.
http://svn.process-one.net/contribs/trunk/eunit/doc/overview-summary.html
Zastanawiałem się, jak testować aktorzy siebie.
Oto, co wymyśliłem, czy ktoś widzi problemy z tym podejściem?
Zamiast wysyłać wiadomości bezpośrednio, a co jeśli Twój aktor delegował wysyłanie wiadomości do funkcji?
Zmodyfikowane testy mogą zamienić się funkcję z jednym, który śledzi liczbę razy zadzwonił i/lub argumentów, z którymi metodę o nazwie:
class MyActor extends Actor {
var sendMessage:(Actor, ContactMsg) => Unit = {
(contactActor, msg) => {
Log.trace("real sendMessage called")
contactActor ! msg
}
}
var reactImpl:PartialFunction(Any, Unit) = {
case INCOMING(otherActor1, otherActor2, args) => {
/* logic to test */
if(args){
sendMessage(otherActor1, OUTGOING_1("foo"))
} else {
sendMessage(otherActor2, OUTGOING_2("bar"))
}
}
}
final def act = loop {
react {
reactImpl
}
}
Twój przypadek testowy może zawierać kod jak:
// setup the test
var myActor = new MyActor
var target1 = new MyActor
var target2 = new MyActor
var sendMessageCalls:List[(Actor, String)] = Nil
/*
* Create a fake implementation of sendMessage
* that tracks the arguments it was called with
* in the sendMessageCalls list:
*/
myActor.sendMessage = (actor, message) => {
Log.trace("fake sendMessage called")
message match {
case OUTGOING_1(payload) => {
sendMessageCalls = (actor, payload) :: sendMessageCalls
}
case _ => { fail("Unexpected Message sent:"+message) }
}
}
// run the test
myActor.start
myActor.reactImpl(Incoming(target1, target2, true))
// assert the results
assertEquals(1, sendMessageCalls.size)
val(sentActor, sentPayload) = sendMessageCalls(0)
assertSame(target1, sentActor)
assertEquals("foo", sentPayload)
// .. etc.
Moja próba jednostkowego przetestowania aktora (działa). Używam Specs jako ramy.
object ControllerSpec extends Specification {
"ChatController" should{
"add a listener and respond SendFriends" in{
var res = false
val a = actor{}
val mos = {ChatController !? AddListener(a)}
mos match{
case SendFriends => res = true
case _ => res = false
}
res must beTrue
}
Jak to działa, wysyłając połączenie synchroniczne do singleton ChatController. ChatController odpowiada za pomocą odpowiedzi (). Odpowiedź jest wysyłana jako zwrot wywoływanej funkcji, która jest zapisywana w mos. Następnie stosuje się dopasowanie, aby uzyskać klasę case, która została wysłana z ChatController. Jeśli wynik jest zgodny z oczekiwaniami (SendFriends), ustaw res na true. Twierdzenie musi być Twierdzeniem określającym powodzenie lub niepowodzenie testu.
Moja aktor Singleton, że jestem testowania
import ldc.socialirc.model._
import scala.collection.mutable.{HashMap, HashSet}
import scala.actors.Actor
import scala.actors.Actor._
import net.liftweb.util.Helpers._
//Message types
case class AddListener(listener: Actor)
case class RemoveListener(listener: Actor)
case class SendFriends
//Data Types
case class Authority(usr: Actor, role: String)
case class Channel(channelName: String, password: String, creator: String, motd: String, users: HashSet[Authority])
object ChatController extends Actor {
// The Channel List - Shows what actors are in each Chan
val chanList = new HashMap[String, Channel]
// The Actor List - Shows what channels its in
val actorList = new HashMap[Actor, HashSet[String]]
def notifyListeners = {
}
def act = {
loop {
react {
case AddListener(listener: Actor)=>
actorList += listener -> new HashSet[String]
reply(SendFriends)
}
}
}
start //Dont forget to start
}
choć jej nie dokończyć to nie zwraca klasę case Sendfriends jak oczekiwano.
- 1. Jednostki testujące zlokalizowane ciągi znaków
- 2. Jednostki testujące filtry akcji - jak kpić z ViewResult
- 3. Moduły testujące jednostki w SAS: FUTS vs SASUnit
- 4. Jak miksować aktorów i aktorów bez typu?
- 5. Jak zapobiegać głodowaniu aktorów w obecności innych długoletnich aktorów?
- 6. Dziedziczenie testów w języku Python: urządzenia testujące jednostki ładunkowe z podklas
- 7. Czy istnieją zautomatyzowane platformy testujące jednostki do testowania wewnętrznej struktury wątków?
- 8. Referencja wzorców kanonicznych w modelu programowania aktorów
- 9. Jak wyznaczyć pulę wątków dla aktorów
- 10. Django SQLite testujące osobliwość: inna ścieżka wykonania?
- 11. Przekazywanie kontekstu żądania bezwarunkowo w systemie aktorów
- 12. Jak testujemy aktorów w Javie?
- 13. Kiedy używać lokalnych lub zdalnych aktorów?
- 14. Przenoszenie typowej architektury trójwarstwowej na aktorów.
- 15. Wysyłanie wiadomości od nie-aktorów w Akce
- 16. Akka zdalnych aktorów, superklasa bez domyślnego konstruktora
- 17. Używanie ScalaTest do testowania akka aktorów
- 18. Począwszy od aktorów Akka w grze
- 19. Używanie aktorów Akka w aplikacji internetowej CRUD
- 20. Jak uruchomić Akka aktorów w IntelliJ IDEA
- 21. jak robić aktorów (erlang) w java?
- 22. Konwencje nazewnictwa dla wiadomości i aktorów Akka
- 23. Przejście z modelu wątku na aktorów
- 24. Akka. Jak zilustrować aktorów w UML?
- 25. Jaki jest koszt tworzenia aktorów w Akce?
- 26. Ręczne tworzenie hierarchii aktorów w akka
- 27. Czy moje obiekty aktorów Akka powinny być oznaczone jako @volatile?
- 28. Jednostki testowe jednostki ABAP - dobre referencje
- 29. Czy biblioteka Akka Actors jest zainstalowana z Scala IDE dla Scala 2.10?
- 30. Serializacja w Scala/Akka
Myślę, że Daniel odnosi się do zastąpienia celu 1 i celu 2 w powyższym teście fałszywym aktorem zbudowanym w ten sposób: var target1 = aktor {reaguj {case OUTGOING_1 (ładunek) {/ * ustaw flagę lub dołącz ładunek. . * /}}} Ale moje wiadomości często zawierają tylko identyfikatory aktorów. Istnieje aktor katalogu, który przekazuje wiadomości do aktora z kluczem identyfikatora. Zamiast zamieniać implementację sendMessage, zamieniłabym relayMessage. Aby zachować powyższy kod powyżej, zostawiłem to wszystko. Ale ogólny pomysł jest taki sam. –