Record method calls in one session for replaying in future test sessions?

前端 未结 9 1331
梦毁少年i
梦毁少年i 2020-12-23 14:21

I have a backend system which we use a third-party Java API to access from our own applications. I can access the system as a normal user along with other users, but I do no

9条回答
  •  余生分开走
    2020-12-23 14:28

    I should prefix this by saying I share some of the concerns in Yves Martin's answer: that such a system may prove frustrating to work with and ultimately less helpful than it would seem at first blush.

    That said, from a technical standpoint, this is an interesting problem, and I couldn't not take a go at it. I put together a gist to log method calls in a fairly general way. The CallLoggingProxy class defined there allows usage such as the following.

    Calendar original = CallLoggingProxy.create(Calendar.class, Calendar.getInstance());
    original.getTimeInMillis(); // 1368311282470
    
    CallLoggingProxy.ReplayInfo replayInfo = CallLoggingProxy.getReplayInfo(original);
    
    // Persist the replay info to disk, serialize to a DB, whatever floats your boat.
    // Come back and load it up later...
    
    Calendar replay = CallLoggingProxy.replay(Calendar.class, replayInfo);
    replay.getTimeInMillis(); // 1368311282470
    

    You could imagine wrapping your API object with CallLoggingProxy.create prior to passing it into your testing methods, capturing the data afterwards, and persisting it using whatever your favorite serialization system happens to be. Later, when you want to run your tests, you can load the data back up, create a new instance based on the data with CallLoggingProxy.replay, and passing that into your methods instead.

    The CallLoggingProxy is written using Javassist, as Java's native Proxy is limited to working against interfaces. This should cover the general use case, but there are a few limitations to keep in mind:

    • Classes declared final can't be proxied by this method. (Not easily fixable; this is a system limitation)
    • The gist assumes the same input to a method will always produce the same output. (More easily fixable; the ReplayInfo would need to keep track of sequences of calls for each input instead of single input/output pairs.)
    • The gist is not even remotely threadsafe (Fairly easily fixable; just requires a little thought and effort)

    Obviously the gist is simply a proof of concept, so it's also not been very thoroughly tested, but I believe the general principle is sound. It's also possible there's a more fully baked framework out there to achieve this sort of goal, but if such a thing does exist, I'm not aware of it.

    If you do decide to continue with the replay approach, then hopefully this will be enough to give you a possible direction to work in.

提交回复
热议问题