diff --git a/ragconnect.tests/src/test/01-input/relation/Test.jadd b/ragconnect.tests/src/test/01-input/relation/Test.jadd
index 3e202c02575049c2809f9bd608eb424537093393..1ada3950c23509e8c2b5381aeb0bf124847c8380 100644
--- a/ragconnect.tests/src/test/01-input/relation/Test.jadd
+++ b/ragconnect.tests/src/test/01-input/relation/Test.jadd
@@ -22,6 +22,7 @@ aspect NameResolution {
   }
 
   // override resolving of SenderRoot for As in ReceiverRoot
+  // TODO change overriden attr to "globallyResolveSenderRootByToken" (should work for all relations in the end)
   refine RefResolverStubs eq A.resolveToMyAByToken(String id) = getParent() != null ? resolveToMyAByTokenInh(id) : null;
 
   inh SenderRoot A.resolveToMyAByTokenInh(String id);
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RelationTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java
similarity index 64%
rename from ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RelationTest.java
rename to ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java
index c2affb34586f144a6462f31021c1ba1d2b44d6c1..4695fec81260fec4cd0f139a4ed1ab3746971ee3 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RelationTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java
@@ -1,6 +1,8 @@
-package org.jastadd.ragconnect.tests;
+package org.jastadd.ragconnect.tests.relation;
 
 import org.assertj.core.groups.Tuple;
+import org.jastadd.ragconnect.tests.AbstractMqttTest;
+import org.jastadd.ragconnect.tests.TestUtils;
 import org.junit.jupiter.api.Tag;
 import relationInc.ast.*;
 
@@ -38,6 +40,9 @@ public class RelationTest extends AbstractMqttTest {
   private static final String TOPIC_BI_OPTIONAL_B = "rel/bi_optional_b";
   private static final String TOPIC_BI_MANY_B = "rel/bi_many_b";
 
+  // FIXME: remove when finished with test
+  private final boolean testing_shortcut = true;
+
   private MqttHandler handler;
   private ReceiverData data;
 
@@ -173,117 +178,178 @@ public class RelationTest extends AbstractMqttTest {
   @Override
   protected void communicateSendInitialValue() throws IOException, InterruptedException {
     // TODO also check disconnect
-    // myA -> a1, myB -> b1
-    // biMyA -> a1, biMyB -> b1
+    // myA -> uni-a1, myB -> uni-b1
+
     check(8, "uni-a1", null, tuple(), "bi-a1", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    // --- testing unmapped unidirectional normal role --- //
+    if (!testing_shortcut) {
+      // --- testing unmapped unidirectional normal role --- //
+
+      uniA(1).setValue("test-1");
+      check(9, "test-1:inner-uni-a1", null, tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      senderUni.setMyA(uniA(2));
+      check(10, "uni-a2", null, tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      // changing something that was previously the relation target must not trigger a message
+      uniA(1).setValue("test-2-ignored");
+      check(10, "uni-a2", null, tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
+
+      uniA(2).setValue("test-3");
+      check(11, "test-3:inner-uni-a2", null, tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      uniA(2).getInner().setInnerValue("test-4");
+      check(12, "test-3:test-4", null, tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      // setting a new relation target resulting in the same serialization must not trigger a message
+      uniA(1).setValue("test-3");
+      uniA(1).getInner().setInnerValue("test-4");
+      senderUni.setMyA(uniA(1));
+      check(12, "test-3:test-4", null, tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
+
+      // --- testing unmapped unidirectional optional role --- //
+
+      // reset a2
+      uniA(2).setValue("uni-a2");
+      uniA(2).getInner().setInnerValue("inner-uni-a2");
+
+      senderUni.setOptionalA(uniA(2));
+      check(13, "test-3:test-4", "uni-a2", tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      uniA(2).setValue("test-5");
+      check(14, "test-3:test-4", "test-5:inner-uni-a2", tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      senderUni.setOptionalA(uniA(1));
+      check(15, "test-3:test-4", "test-3:test-4", tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      // change a nonterminal target of two relations must trigger two messages
+      uniA(1).getInner().setInnerValue("test-6");
+      check(17, "test-3:test-6", "test-3:test-6", tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      // setting an optional relation to null is allowed, but must not trigger a message
+      senderUni.setOptionalA(null);
+      check(17, "test-3:test-6", "test-3:test-6", tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
+
+      // setting the previous nonterminal as relation target again won't trigger a message
+      senderUni.setOptionalA(uniA(1));
+      check(17, "test-3:test-6", "test-3:test-6", tuple(), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
+
+      // --- testing unmapped unidirectional list role --- //
+
+      senderUni.addManyA(uniA(3));
+      check(18, "test-3:test-6", "test-3:test-6", tuple("uni-a3"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      uniA(3).setValue("test-7");
+      check(19, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      senderUni.addManyA(uniA(2));
+      check(20, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-5:inner-uni-a2"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      senderUni.addManyA(uniA(1));
+      check(21, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-5:inner-uni-a2", "test-3:test-6"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      uniA(2).getInner().setInnerValue("test-8");
+      check(22, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-5:test-8", "test-3:test-6"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      senderUni.removeManyA(uniA(2));
+      check(23, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-3:test-6"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple());
+
+      // disconnect my-a, optional-a, many-a - resetting afterwards must not trigger a message
+      senderUni.disconnectMyA(mqttUri(TOPIC_MY_A));
+      senderUni.disconnectOptionalA(mqttUri(TOPIC_OPTIONAL_A));
+      senderUni.disconnectManyA(mqttUri(TOPIC_MANY_A));
+      uniA(1).setValue("a1");
+      uniA(1).getInner().setInnerValue("inner-a1");
+      uniA(2).setValue("a2");
+      uniA(2).getInner().setInnerValue("inner-a2");
+      uniA(3).setValue("a3");
+      uniA(3).getInner().setInnerValue("inner-a3");
+      check(23, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-3:test-6"), "bi-a1", null, tuple(),
+              "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
+    } else {
+      data.numberOfValues = 23;
+    }
+
+    // "reset" values in receiver-root to make check method call shorted
+    receiverRoot.setFromMyA(null);
+    receiverRoot.setFromOptionalA(null);
+    receiverRoot.setFromManyAList(new JastAddList<>());
+    check(23, null, null, tuple(), "bi-a1", null, tuple(),
+            "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    uniA(1).setValue("test-1");
-    check(9, "test-1:inner-uni-a1", null, tuple(), "bi-a1", null, tuple(),
+    // biMyA -> bi-a1, biMyB -> bi-b1
+    // --- testing unmapped bidirectional normal role --- //
+    biA(1).setValue("test-9");
+    check(24, null, null, tuple(), "test-9:inner-bi-a1", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    senderUni.setMyA(uniA(2));
-    check(10, "uni-a2", null, tuple(), "bi-a1", null, tuple(),
+    // set opposite role of relation must trigger message
+    biA(2).setToMyA(senderBi);
+    check(25, null, null, tuple(), "bi-a2", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
     // changing something that was previously the relation target must not trigger a message
-    uniA(1).setValue("test-2-ignored");
-    check(10, "uni-a2", null, tuple(), "bi-a1", null, tuple(),
+    biA(1).setValue("test-9-ignored");
+    check(25, null, null, tuple(), "bi-a2", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
 
-    uniA(2).setValue("test-3");
-    check(11, "test-3:inner-uni-a2", null, tuple(), "bi-a1", null, tuple(),
+    biA(2).setValue("test-10");
+    check(26, null, null, tuple(), "test-10:inner-bi-a2", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    uniA(2).getInner().setInnerValue("test-4");
-    check(12, "test-3:test-4", null, tuple(), "bi-a1", null, tuple(),
+    biA(2).getInner().setInnerValue("test-11");
+    check(27, null, null, tuple(), "test-10:test-11", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
     // setting a new relation target resulting in the same serialization must not trigger a message
-    uniA(1).setValue("test-3");
-    uniA(1).getInner().setInnerValue("test-4");
-    senderUni.setMyA(uniA(1));
-    check(12, "test-3:test-4", null, tuple(), "bi-a1", null, tuple(),
+    biA(1).setValue("test-10");
+    biA(1).getInner().setInnerValue("test-11");
+    biA(1).setToMyA(senderBi);
+    check(27, null, null, tuple(), "test-10:test-11", null, tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
 
-    // --- testing unmapped unidirectional optional role --- //
-
+    // --- todo testing unmapped bidirectional optional role --- //
     // reset a2
-    uniA(2).setValue("uni-a2");
-    uniA(2).getInner().setInnerValue("inner-uni-a2");
+    biA(2).setValue("bi-a2");
+    biA(2).getInner().setInnerValue("inner-bi-a2");
 
-    senderUni.setOptionalA(uniA(2));
-    check(13, "test-3:test-4", "uni-a2", tuple(), "bi-a1", null, tuple(),
+    senderBi.setBiOptionalA(biA(2));
+    check(28, null, null, tuple(), "test-10:test-11", "bi-a2", tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    uniA(2).setValue("test-5");
-    check(14, "test-3:test-4", "test-5:inner-uni-a2", tuple(), "bi-a1", null, tuple(),
+    biA(2).setValue("test-12");
+    check(29, null, null, tuple(), "test-10:test-11", "test-12:inner-bi-a2", tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    senderUni.setOptionalA(uniA(1));
-    check(15, "test-3:test-4", "test-3:test-4", tuple(), "bi-a1", null, tuple(),
+    // set opposite role of relation must trigger message
+    biA(1).setToOptionalA(senderBi);
+    check(30, null, null, tuple(), "test-10:test-11", "test-10:test-11", tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
     // change a nonterminal target of two relations must trigger two messages
-    uniA(1).getInner().setInnerValue("test-6");
-    check(17, "test-3:test-6", "test-3:test-6", tuple(), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple());
-
-    // setting an optional relation to null is allowed, but must not trigger a message
-    senderUni.setOptionalA(null);
-    check(17, "test-3:test-6", "test-3:test-6", tuple(), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
-
-    // setting the previous nonterminal as relation target again won't trigger a message
-    senderUni.setOptionalA(uniA(1));
-    check(17, "test-3:test-6", "test-3:test-6", tuple(), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
-
-    // --- testing unmapped unidirectional list role --- //
-
-    senderUni.addManyA(uniA(3));
-    check(18, "test-3:test-6", "test-3:test-6", tuple("uni-a3"), "bi-a1", null, tuple(),
+    biA(1).getInner().setInnerValue("test-13");
+    check(32, null, null, tuple(), "test-10:test-13", "test-10:test-13", tuple(),
             "uni-b1", null, tuple(), "bi-b1", null, tuple());
 
-    uniA(3).setValue("test-7");
-    check(19, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3"), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple());
-
-    senderUni.addManyA(uniA(2));
-    check(20, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-5:inner-uni-a2"), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple());
-
-    senderUni.addManyA(uniA(1));
-    check(21, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-5:inner-uni-a2", "test-3:test-6"), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple());
-
-    uniA(2).getInner().setInnerValue("test-8");
-    check(22, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-5:test-8", "test-3:test-6"), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple());
-
-    senderUni.removeManyA(uniA(2));
-    check(23, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-3:test-6"), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple());
-
-    // disconnect my-a, optional-a, many-a - resetting afterwards must not trigger a message
-    senderUni.disconnectMyA(mqttUri(TOPIC_MY_A));
-    senderUni.disconnectOptionalA(mqttUri(TOPIC_OPTIONAL_A));
-    senderUni.disconnectManyA(mqttUri(TOPIC_MANY_A));
-    uniA(1).setValue("a1");
-    uniA(1).getInner().setInnerValue("inner-a1");
-    uniA(2).setValue("a2");
-    uniA(2).getInner().setInnerValue("inner-a2");
-    uniA(3).setValue("a3");
-    uniA(3).getInner().setInnerValue("inner-a3");
-    check(23, "test-3:test-6", "test-3:test-6", tuple("test-7:inner-uni-a3", "test-3:test-6"), "bi-a1", null, tuple(),
-            "uni-b1", null, tuple(), "bi-b1", null, tuple(), true);
-
-    // --- todo testing unmapped bidirectional normal role --- //
-
-    // --- todo testing unmapped bidirectional optional role --- //
-
     // --- todo testing unmapped bidirectional list role --- //
 
     // --- todo testing transformed unidirectional normal role --- //