question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

introduce and encourage use of an interface that is more easily testable

See original GitHub issue

I’ve had some difficulty writing good unit tests for WebSocketClientProtocol-based implementations. The tools available seem to encourage one of two paths:

  • Directly instantiate the relevant objects and then call methods on them as though they were in use by the real Autobahn WebSocket implementation.
  • Set up real network servers and clients that interact over real sockets so that the real Autobahn WebSocket implementation is driving them.

The first of these options has the drawback that there’s no guarantee the tests will actually drive the application code correctly (and even if it is initially correct the chances of it diverging from reality increase as Autobahn is maintained and changed).

The second of these options has the drawback that it is prone to many different kinds of spurious failure (most code that takes this approach doesn’t even manage to get the part where you start listening on a port correct 😢 ). It also draws in a lot more code and so failures can become harder to spot. Failures can also end up being caused by other code that’s not the main focus of the test. It’s also a lot slower/more expensive as a result of running so much more code.

I think it would be very useful if Autobahn itself offered and encouraged the use of a higher-level interface that allows details about connections/sockets/networks to be contained in an object that can easily be substituted for a testing fake. A model for this which appears to be working well is the regular HTTP client interface in Twisted, twisted.web.client.IAgent. This has one primary network-enabled implementation in Twisted, twisted.web.client.Agent and the third-party(-ish) treq library provides a test-focused implementation, treq.testing.RequestTraversalAgent.

Application code written against IAgent can accept an implementation and do what it needs to do. Real-world use of this application code passes in an Agent instance (or possibly a wrapper but that’s not directly relevant here). Test use of this same application code passes in a correctly initialized RequestTraversalAgent. The application code doesn’t know or care which implementation it gets. Agent goes off and makes real requests over a real network. RequestTraversalAgent decomposes the request and serves up a response to it using a twisted.web.resource.IResource provider - with no network, only Python method calls and correct copying of bytes from one place to another in memory.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:23 (22 by maintainers)

github_iconTop GitHub Comments

1reaction
meejahcommented, Mar 27, 2019

So, I think I’m proposing: IWebSocketClientAgent.open() takes something that contains all the options (or, maybe, has kwargs that are the options?). This object would be very much like how Factory is already (ab)used, right?

0reactions
ambsw-technologycommented, Nov 2, 2019

Was this closed by #1186 or are there residual improvements to be implemented?

Read more comments on GitHub >

github_iconTop Results From Across the Web

5 Reasons Why Interfaces Are More Important Than You Think
Interfaces encourage testable code. Interfaces foster the single responsibility principle and interface segregation principle.
Read more >
Unit Tests, How to Write Testable Code, and Why It Matters
In this article, I will show that unit testing itself is quite easy; the real problems that complicate unit testing, and introduce expensive...
Read more >
What are the design principles that promote testable code ...
Yes, SOLID is a very good way to design code that can be easily tested. As a short primer: S - Single Responsibility...
Read more >
Should you always Code To Interfaces In Java - Stack Overflow
No, every class should not have an interface. It's overkill squared. You use an interface when you need ...
Read more >
Testable code best practices - SitePen
One of the keys to writing highly testable code is to ensure that there is a strong separation between the different parts of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found