I’m wondering whether there are any resources available on how to test apps written in panel using e.g. tools like selenium.
E.g. for selenium I need a programmatic way to access the individual components of my app from the html (say, a file upload / a button / … widget) and I notice that panel does not add
id attributes to the corresponding html tags.
E.g. one could imagine a “mode” where the
name argument that is passed to many of the panel widgets is set as the
id attribute of the corresponding html tags.
I’d be interested to learn about best practises on how to do this type of testing with panel (also, if you recommend other approaches for panel).
I have been thinking about Selenium tests as well. But I think they are not really needed.
The reason being that you can do the most important tests from unit to functional tests in python alone. (I believe).
If you develop your app as a
param.Parameterized class then you can simply test your app in python.
For example an app where the user can select a day of the week and a table should filter to the day of the week.
app.selection = "monday"
Of course this does not test that the table updates in the UI or that the selection is placed over the table (or to the right of the table). But to me that is of lesser importance/ risk though.
Also in my experience Selenium tests take a lot of time to develop and are unstable. Thus I believe I get much more value/ effort out of writing python tests than selenium tests.
Thanks for your input @Marc !
If things can be easily tested in the way you suggest, that seems even better.
Do you happen to know of example code for testing user input like file upload, button clicks etc. as well?
I have some of those types of tests here: PyHDX/test_gui.py at master · Jhsmit/PyHDX · GitHub
However, they are slow and do not test everything (as I’ve just found)
Testing uploading files I do like this:
from pathlib import Path
import panel as pn
f_bin = Path('testfile.txt').read_bytes()
widget = pn.widgets.FileInput(multiple=True)
# if not multiple, just assign f_bin directly
widget.value = [f_bin]
# testing code ...
btn1 = param.Action(lambda self: self._btn1_action())
my_buttons = MyButtons()
# Emulate button press: