Splitting Apps for Testing

I’ve started splitting my apps into four:

1 - Forms
2 - Modules
3 - Server Modules
4 - Services

The Forms app is the one that’s published to users and it has dependencies on the other three. The forms themselves are as ‘dumb’ as I can make them with as much code as possible pushed down to the Modules or Server Modules apps.

I’ve found this incredibly useful for testing purposes. I create (yet) more testing apps for the modules and server modules layers. Those testing apps are dependent on the development version of the layer they test but the published version of the other layers. (If I want to test more than one layer, a testing app might be dependent on the development version of several layers).They also have their own services so that testing data is separate from production.

It adds some overhead - the list of apps gets long, the dependencies have to be managed carefully, data tables have to be created in several places - but, for me, the benefit far outweighs that cost. The forms and services layers rely purely on Anvil itself and I tend not to test them. Any functionality that I’m writing goes in the modules or server modules layers and is tested.

Anyone else doing anything similar?

3 Likes

I agree with the splitting the app in smaller chunks. The number of apps increases, but the complexity decreases. Not only for testing, for the app management in general.

I test the server modules with PyCharm.

In my computer I have a folder structure similar to this:

App
  XYZXYZXYZ
    .git
      [...]
    forms
      Main.py
      Main.yaml
    server_modules
      ServerModule1.py
      ServerModule2.py
    theme
      [...]
  TestSuite
    .git
      [...]
    test1.py
    test2.py
    test_uplink1.py
    test_uplink2.py
  Uplink
    .git
      [...]
    uplink1.py
    uplink2.py

I create the XYZXYZXYZ folder by cloning the Anvil repository. Then I create the TestSuite and Uplink folders.

At this point I have 3 folders, each with a git repository, inside the same app folder. I start PyCharm, open the app folder as a new project and PyCharm manages the 3 repositories (almost) as if they were one. This allows me to test all the logic in the server and the uplink modules.

I do all the editing of the server modules in PyCharm, way more powerful than in the online IDE. I keep the online IDE only for form editing.

It is easy to configure PyCharm so that tests and uplinks can import server modules.
It is less easy to import server modules from dependency apps. I am working on one right now, I will see how far I can go.

I just started testing the interface using this technique and it’s promising. Bryndon just found a bug that had been bugging him for days.

1 Like

I’ve found that works fine for unit testing of server modules, but when I wanted integration testing that involves the data tables, secrets or users services, it becomes difficult to test on my local machine.

Testing with data tables works well. I would say it’s a must, to make sure that uplink modules are reliable.

The only problem is that it is slower than testing on the server because every access to a table is a round trip. I had a test failing because I was comparing the time required to do the same job in two ways and I wanted to make sure that way A would be faster than way B. I had to remove that test.

I have no experience with secrets and I have not seriously tested user services yet.

1 Like

I’m starting to think a combination of the two approaches might be even better!!

If I split my apps into layers but do my testing locally for modules and server modules, that might work nicely.

I’d still have to create an Anvil ‘Testing App’. It would contain the necessary services, the dependencies on other apps and provide an uplink for the the local test suite, but it wouldn’t have any code itself. I’ll have a play…

1 Like

Yep. I’ve hit this problem too. Not found a solution yet…

this works: create a testing app with all the necesary dependencies and also the unittesting code. Add a test runner function which is decorated with @anvil.server.callable

That can now be called from a form in the app and run within the Anvil ide.

It can also be called locally - the tests execute on the anvil instance, but they can be edited locally and the test results are visible locally too.

2 Likes

I clone both the app that I am testing and the dependency app, then, in PyCharm, I add the server_modules folder of the dependency app as source to the project structure of the main app, then I import like this:

try:
  from DependencyApp import ServerModule1
except:
  import ServerModule1

The first import works inside Anvil, the second works inside PyCharm. Unfortunately I need to modify the code just to make the testing happy. Please let me know if there is a better way.

The result is a PyCharm environment that allows me not only to test but also to debug, because the code runs on my machine. When I work on classes with complex behavior, I start by writing the tests, then I add the code and debug my way through a working test suite. At this point I go back to Anvil and build the interface on top of a well tested set of modules.

1 Like