Search Unity

Help Wanted How to access script from different Assembly in play mode testing?

Discussion in 'Testing & Automation' started by unity_3rwby93b8roxIQ, Jan 11, 2021.

  1. unity_3rwby93b8roxIQ

    unity_3rwby93b8roxIQ

    Joined:
    Jan 11, 2021
    Posts:
    4
    Hello,
    I am new with Unity test framework and have encountered a problem.
    I want to access a script attached to a GameObject in the scene that I load in the beginning of the test.
    The problem occurs in the bolded areas: The type or namespace name '****' could not be found (are you missing a using directive or an assembly reference?

    How can I access methods in script attached to a gameObject in a scene I open with a test?
    Thanks for the help:)



    Code:
    using System.Collections;
    using System.Collections.Generic;
    using NUnit.Framework;
    using UnityEngine;
    using UnityEngine.TestTools;
    using UnityEngine.SceneManagement;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    using *name of my assembly

    namespace Tests
    {
    public class Test1
    {
    private GameObject otherGameObject;
    private MyScriptName myScriptName;

    [UnityTest]
    public IEnumerator Test1WithEnumeratorPasses()
    {
    SceneManager.LoadScene("NameOfMyScene");
    yield return new WaitForSecondsRealtime(5);
    otherGameObject = GameObject.Find("GameObjectWithScript");
    myScriptName = otherGameObject.GetComponent<MyScriptName>();

    yield return null;
    }
    }
    }
     
  2. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,486
    In the Inspector for the asmdef that covers your tests, you need to add a reference to the asmdef that covers the code you want to use.
     
  3. unity_3rwby93b8roxIQ

    unity_3rwby93b8roxIQ

    Joined:
    Jan 11, 2021
    Posts:
    4
    But what if all of my code is under Assembly-CSharp. And I cant put my code under some other assembly.
    Is it possible in that case?
     
  4. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,486
    No, unfortunately tests cannot access classes in Assembly-CSharp. You could put an asmdef in the root of your assets folder to cause 'all code not otherwise in an asmdef' to be put into one big assembly, though. (If you have 'Editor' folders in your project then you might need to add separate asmdefs for them).
     
    unity_3rwby93b8roxIQ likes this.
  5. unity_3rwby93b8roxIQ

    unity_3rwby93b8roxIQ

    Joined:
    Jan 11, 2021
    Posts:
    4
    Thank you for information :)
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,577
    Any chance whatsoever that you'll consider supporting this? It turned out (for us at least) that the asmdef workflow was strictly worse in every single way than the "old" workflow, so after shipping a game with asmdefs, we've hard pivoted back and are much, much happier.

    But it does makes testing a pain, since we can't access any of our code directly, and essentially end up having to rely on GetComponent(string) and reflection, which is annoying.

    It would require being able to define that some assembly definitions run after the built-in rather than before, but really tests always need to be compiled last, and having a testing framework that says "the tests will be compiled before some of your code" is just silly.
     
  7. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,486
    Unlikely; more likely that we will improve asmdefs. What problems did you run into?
     
  8. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,577
    There were simply no real benefits. We had this idea that we would be able to use them to help properly structure the game code, but it turned out that all of our systems kinda wanted to know about each other occasionally. So the task of figuring out which assemblies needed to exist, and which ones that needed to have dependencies to which ended up being very, very hard.

    So they ended up having like 15 dependencies each, so our compile and enter play mode times got utterly trashed, and we very often had to make interfaces with a single implementation just to pass around data, or create events where we really should just be calling a method directly.

    We should have backed out, but that ended up not being feasible for reasons that I can't quite remember - except that one of them was that we had a big unit testing suite that we'd just have to toss if we wanted to.

    So they made the code harder to write, harder to read, and slower to compile. So pretty much exactly the inverse of the intention.

    It's also just so much easier to just throw an editor folder in there and have it work the first time. With the asmdef workflow, we have to add the assembly definition, wait for the entire codebase to fail to recompile, add the correct dependencies and click all the correct checkboxes, and then get it to work. So adding editors to something that didn't use to have editors turned into a several minute process that had the possibility of making errors when doing instead of just making a damn folder.

    We were super hyped about asmdefs. The idea was great on paper, so we bought in hard. The end result was three years of wasted effort in supporting a feature that slowed us down. We'd have been much happier as programmers if we'd just have skipped it.


    These days I think the feature just doesn't have much merit inside a scripts folder. If there's a part of the project that's stable enough to pull out and turn into a dependency instead of something that's in flux, that becomes a package, no an assembly.

    As of now, I consider rolling our own unit testing framework as less work than putting our code in asmdefs.
     
  9. Kleptine

    Kleptine

    Joined:
    Dec 23, 2013
    Posts:
    167
    What we do is just have one very large assembly for most of our gameplay code, and only make separate asmdefs for other code that is clearly self-contained. That's worked out fine for tests so far, for us.

    I do agree that more asmdefs = more problems. Games really don't want to be a DAG of dependencies, haha. We did it more fine-grained for a while, and it was clear that didn't work well.
     
  10. HaraldNielsen

    HaraldNielsen

    Unity Technologies

    Joined:
    Jun 8, 2016
    Posts:
    80
    Hi, I guess we could add the possibility of having test's reference Assembly-Csharp and friends.
    Can you report a bug and then we can look into adding that possibility.

    The real reason it was not added, is that you have a bigger risk of circular dependencies with this addition.
    Assembly-CSharp and friends reference all asmdef's by default. Asmdef's can opt out of that by disabling "Auto Referenced". But that should really be solved with tooling instead of limiting functionality.
     
    Baste likes this.
  11. HaraldNielsen

    HaraldNielsen

    Unity Technologies

    Joined:
    Jun 8, 2016
    Posts:
    80
    You could add asmdef's as @superpig suggests for the root, and a new one + Asmref's for /Editor folders. Then you can control all references directly, and have tests.
    Alternatively there is a option in the Test Framework UI to include test references for all assemblies. So you can then write tests in Assembly-CSharp and frieds. The downside is that is part of you gamecode now unless if you try to handle that with preprocessors
     
  12. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,577
    Sorry for taking forever, but Case 1331217 has been posted.

    As I stated in the bug report, If you take a step back and look at the situation, it's somewhat absurd to have a test framework for Unity that can't be used to test the default way of writing code for Unity.
     
    stevospinks likes this.
unityunity