python-websockets / websockets

Library for building WebSocket servers and clients in Python
https://websockets.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
5.16k stars 513 forks source link

How to unit test client code? #1391

Closed snarfed closed 1 year ago

snarfed commented 1 year ago

Hi! First of all, thank you for building and maintaining websockets. It's great!

I'm using the sync client, and I was able to get up and running with it in no time. Awesome. I'm now trying to unit test my code, though, and I'm having trouble. Are there recommended patterns for unit tests?

I searched the docs and issues here, and the web, but didn't find anything. Your own tests have some helpers that look useful, eg InterceptingConnection and RecordingProtocol:

https://github.com/python-websockets/websockets/blob/adfb8d69a7a1f6f4c8381c9e7182619d202c3cf2/tests/sync/test_connection.py#L30-L35

...but they're not included in the library. Any other suggestions?

Thanks in advance!

snarfed commented 1 year ago

For now, I might try implementing a minimal version of InterceptingConnection and injecting it into to connect's create_connection kwarg. Will see how that goes. I'm still definitely interested in more official ideas long term though!

aaugustin commented 1 year ago

The easiest way to test a client is usually to run a server and connect to it.

Furthermore, you should design your client so you can test as much of logic as possible without I/O. Then only perform a few integration tests to make sure that it can connect to a server. This is the approach taken by websockets with e.g. tests/sync/test_connection.py (integration tests, doing I/O) being much smaller than tests/test_protocol.py (testing logic without doing I/O)

InterceptionConnection is designed to break some rules that websockets enforces, in order to test how a client reacts to a misbehaving server and vice-versa. RecordingProtocol keeps track of every frame sent the connection, which is a library level concern, while you want to test a the application level. Exposing them wouldn't encourage good testing patterns (IMO).

snarfed commented 1 year ago

Thank you! That all makes sense, will do.