Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Bug Several issues with code dependencies in tests

Discussion in 'Testing & Automation' started by Alan47, Mar 1, 2019.

  1. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    Hi,
    I'm writing some Play-Mode-Tests in Unity 2018.3.6f1 in C#. I noticed that:
    1. In order to use the classes defined in the regular code in my test assembly, I need an assembly definition (*.asmdef) in my main code folder, and that needs to be linked in the tests.asmdef. This isn't really obvious and took me quite some time to figure out. The editor UI should warn about this somewhere.
    2. Even though "using static" declarations work well in the main assembly, it is not possible to use "using static" in the test assembly to import something from the main assembly. The error says that the referenced class simply cannot be found.
    3. I noticed that creating a C# extension function inside a test class that references a main assembly class as "this" has the effect that the compiler cannot find the extension method in the test.
    I don't know if 2) and 3) above are actual C# issues or unity issues, but either way they're quite annoying.
     
  2. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,576
    For 2) and 3), I assume that you're able to use the classes usually inside the tests assembly, you just can't use them with "using static" or with extension methods?
     
  3. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    Yes, after doing step 1) I can import them as usual with "using" in my test assembly. However, in the same scenario, "using static" on a main assembly class doesn't work in a test assembly class.

    For the extension methods, here's an example:

    Code (CSharp):
    1.  
    2. using MyMainClass; // from main assembly
    3.  
    4. class MyTestClass {
    5.  
    6.     [Test]
    7.     public void RunTest(){
    8.          MyMainClass instance = new MyMainClass();
    9.          instance.ExtensionMethod(); // error: not found
    10.     }
    11.  
    12.     // will not be found by the compiler
    13.     public static void ExtensionMethod(this MyMainClass instance){
    14.  
    15.     }
    16.  
    17. }

    It's not really breaking, everything here can be worked around, it's just awkward when you first run into it.

    I only use C# for coding in Unity. I don't know if these are Unity issues or general C#/.NET issues.
     
    Last edited: Mar 1, 2019
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,076
    Extension methods should be defined in static classes, see here.

    Issue 2 sounds like a bug, do you have an example of that as well?
     
  5. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    Oh ok I see... I wonder why the compiler didn't complain about the declaration then? I usually write Kotlin code, and in Kotlin you can define extension methods pretty much anywhere, so I didn't notice that. I was mislead by the error message saying that the method couldn't be found when actually the declaration was invalid. Thanks for the heads-up!

    I do. The following setup gave me a lot of trouble:

    Main Assembly Class:
    Code (CSharp):
    1. public static class XYUtils {
    2.  
    3.     public const int SomeUsefulConstant = 1234;
    4.  
    5.     public static String SayHello(){ return "Hello"; }
    6.  
    7. }
    Test Assembly Class:
    Code (CSharp):
    1. // the usual test includes for unity go here
    2. using static XYUtils;  // NOPE: not found (maybe the lack of a namespace causes troubles here?)
    3.  
    4. public class MyTest {
    5.  
    6.     [Test]
    7.     public void runTest(){
    8.         Assert.AreEqual(1234,SomeUsefulConstant); // not found
    9.         Assert.AreEqual("Hello", SayHello()); // not found
    10.     }
    11.  
    12. }
    However, this test class works just fine:

    Test Assembly Class v2:
    Code (CSharp):
    1. // the usual test includes for unity go here
    2.  
    3. public class MyTest {
    4.  
    5.     [Test]
    6.     public void runTest(){
    7.         Assert.AreEqual(1234, XYUtils.SomeUsefulConstant); // ok
    8.         Assert.AreEqual("Hello", XYUtils.SayHello()); // ok
    9.     }
    10.  
    11. }

    In the main assembly, I can use either the "using static" statement and just "SomeUsefulConstant" or use the qualified name "XYUtils.SomeUsefulConstant", both work. In the test assembly, the "using static" option doesn't seem to work. Or maybe I'm just doing it wrong?
     
  6. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    Hi,

    I tried the "using static" thing again today with a different example and this time it miraculously worked. I'm not sure what I did wrong last time though. I'll report back if I run into it again.