Providing guidance for __app__ in the face of unit testing
See original GitHub issueIf you look at the unit testing example, you will notice it uses relative imports. If you look earlier in that same page you will notice that the suggested folder structure has the folder containing the function files be named FunctionApp
. The problem is that if the unit testing code were to switch to using absolute imports and thus import from __app__
, then the unit testing example will fail with an ImportError
.
I think there are two ways to solve this. One is to not encourage people to use __app__
. If you do this then the current recommended practice of making FunctionApp
the folder you commit to git and naming it appropriately for your project can continue. That does also mean, though, that beyond discouraging absolute imports via __app__
you will also need to document how run test runners like pytest such that they know where the root of the project is. This is important because if the unit testing example were to suddenly include an import for shared code – from ..SharedCode import myFirstHelperFunction
as listed in the folder structure example – it would fail as pytest .
from within your project/git checkout wouldn’t know where the module root was (it works now because pytest just thinks myapp
is the top-level package thanks to it only referencing code from within that folder). And you can’t do pytest ..
as that would cause pytest to search all folders in the parent folder for tests which could be a lot if you keep all of your git clones in a single directory (e.g. all of my GitHub clones are in a Repositories/
folder, so pytest ..
would search 5 other repositories on the machine I’m typing from). And so some guidance for how people should tell pytest how to run their tests appropriately would be required (on top of advising people not to use __app__
).
The other option is to change the folder structure guidance to be more like the following (see the functions version of pvscbot to see this working in a deployed function):
FunctionApp
| - __app__
| | - __init__.py
| | - MyFirstFunction
| | | - __init__.py
| | | - function.json
| | - MySecondFunction
| | | - __init__.py
| | | - function.json
| | - SharedCode
| | | - myFirstHelperFunction.py
| | | - mySecondHelperFunction.py
| | - host.json
| | - requirements.txt
By embracing the fact that the package needs to be named __app__
you avoid all of the above mentioned issues with pytest and breaking unit tests if you start using absolute imports without naming your git repository appropriately. It also has a nice side-effect of letting people keep their tests and related requirements specifications outside of the folder that gets deployed to Azure (which should speed up deployment; see the sample repo I linked to above to see how to make a dev-requirements.txt
refer to __app__/requirements.txt
to practice DRY with dependencies).
The problem is this solution obviously goes against the guidance to have the folder that func init
creates for you be what becomes your git repository (e.g. the example on how to use Azure Pipelines for CD won’t work out-of-the-box as you now need to deploy a sub-folder of your repository). It also means that func new
is creating a .vscode
folder in the wrong location.
Anyway, it would be great to solve this somehow as unit testing stateless functions on Azure is really nice and simple thanks to HttpRequest
having a constructor that is easy to work with.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:9
- Comments:13 (2 by maintainers)
Top GitHub Comments
Sorry for the long waiting, we updated the Python worker to accept import statements without using __app__ namespace, which should be much cleaner and intuitive. I’ve updated the folder structure, import behavior and unit testing guide in our official docs: https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-python#folder-structure
@jeffhollan is there an update yet on this? Calling the project dir “app” is not a good workaround.