hyperoceanic

hyperoceanic

Testing ECSx.Components and Systems

I"m working on a Kanban simulator, and I’m having some problems getting started with testing. The error message I’m getting is

** (ArgumentError) errors were found at the given arguments:

 * 1st argument: the table identifier refers to an ETS table with insufficient access rights
    

Here’s my Component:

defmodule Taiichi.Components.StoryPoints do
  use ECSx.Component,
    value: :integer
end

And here’s my test:

 test "sets remaining points to story points if not assigned" do

        task = Ecto.UUID.generate()
        StoryPoints.add(task, 100)
        
        found = StoryPoints.get_all()
        assert Enum.any?(found)
    end

It’s the StoryPoints.add(task, 100) that causes the error.

I had a look at the tests in the main Ecsx repo and in the example Ship repo but could not see any tests that did something similar with a Component in an application vs one that is stood up in the test itself.

I can insert the component if I do it in the Manager, back in the main application.

I think the issue is that the ETS table is owned by the application process not the test process but I could not find an example that showed how to get this to work.

Is there some guidance on using ETS-dependent code in tests?

First Post!

APB9785

APB9785

Creator of ECSx

Hi Mark, and thanks for using ECSx!

You’re right that ETS tables are owned by the Manager and cannot be written to from any other process. This is to ensure data consistency while Systems are running. However, there is of course a need for various client processes to make updates to Component data, so the answer in ECSx is ClientEvents.

In your case, the client is the Test process, which would like to create a StoryPoints Component. Instead of having that Test process attempt StoryPoints.add/2 directly, it should call ECSx.ClientEvents.add/2 to create a ClientEvent. Then a ClientEventHandler System (which runs from the Manager) can detect the event and add the StoryPoint Component.

This strategy for updating Components via ClientEvents is also used in the Ship tutorial - Client Input via LiveView

Some other notes specifically about testing:

ECSx (and Entity-Component-System apps in general) manage data over time, using tick intervals. This means that updates to data don’t happen right away, but wait until the next tick. This can cause some difficulties when testing, especially if the tick rate is low. You can either raise the tick_rate config in testing, or manually send a :tick message to the Manager when needed.

Also, since ECSx uses global shared state (GenServer, ETS), the effects of your updates to Component data can be seen by all other tests. There is no “sandboxing” of the Component data to isolate side-effects to an individual test. If you create different entity IDs for each test, you can somewhat avoid conflicts, but patterns such as

found = StoryPoints.get_all()
assert Enum.any?(found)

can be problematic if another test is also creating StoryPoints components (each test will see the components created by the other test).

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

We're in Beta

About us Mission Statement