Test execution control method, apparatus, and system
By using thread event objects and delegate closure mode, the limitations of cross-thread operations in browser automation frameworks are resolved, enabling reliable control of the test lifecycle and improving the stability and efficiency of the test service. This approach is suitable for automated testing scenarios in web applications.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- BEIJING QBOSON QUANTUM TECH CO LTD
- Filing Date
- 2026-04-27
- Publication Date
- 2026-06-19
AI Technical Summary
Existing browser automation frameworks do not support cross-thread operations, leading to difficulties in test lifecycle management, poor transmission of pause and stop signals, resource residues when exiting abnormally, and a lack of service-oriented design, which affects the reliability and efficiency of testing.
By employing a blocking and waiting mechanism based on thread event objects and a delegated shutdown pattern, combined with web interface control over the test lifecycle, browser resources are safely closed by determining thread identity, and signal handling functions and process exit hooks are registered to ensure resource cleanup, thus realizing the service-oriented design of the test engine.
It enables safe shutdown of cross-thread operations, reduces CPU consumption, improves the timeliness of stopping operations and resource utilization, reduces the risk of browser zombie processes, and enhances the robustness and observability of the test service.
Smart Images

Figure CN122240507A_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of software automated testing technology, and in particular to a test execution control method, apparatus and system. Background Technology
[0002] Currently, web automation testing typically relies on browser automation frameworks (such as Selenium and Playwright) to drive the browser to execute test operations. In test management scenarios, the test platform needs to run as a web service, with users initiating tests, viewing progress, pausing, and stopping tests through a browser frontend. This architecture requires the test engine to execute the test process in a background thread while simultaneously responding to frontend control commands. However, existing technologies have the following shortcomings: (1) Thread model limitations of browser automation frameworks. Mainstream browser automation frameworks (such as Playwright) do not support cross-thread operations, meaning that the browser instance must be operated and closed in the thread in which it was created. When the web server receives a user's stop request, the thread that handles the HTTP request is not the same thread as the worker thread that executes the test. Closing the browser directly in the request handling thread will cause the framework to malfunction or resource leaks.
[0003] (2) Signal transmission issues during pause and stop. When the test thread is in a paused state (blocked and waiting for a resume signal), if the user issues a stop command, the stop signal cannot be transmitted to the blocked thread. Existing solutions usually use polling to check the flag bit to implement pause, which leads to continuous CPU consumption during the pause.
[0004] (3) Resource remnants during abnormal termination. When the test service terminates abnormally (such as when the user presses Ctrl+C, the operating system sends a SIGTERM signal, or the process is forcibly killed), the browser process started by the automation framework may become a zombie process that remains in the system, occupying system resources and ports, and affecting the normal execution of subsequent tests.
[0005] (4) The test engine lacks a service-oriented design. Most existing test frameworks exist as command-line tools or libraries, and the test lifecycle (start, pause, resume, stop, and complete) is manually managed by developers in scripts. There is a lack of a design paradigm that hosts the test engine itself as a persistent service and monitors it remotely via a web interface.
[0006] There is currently no effective solution to the above problems. Summary of the Invention
[0007] This application provides a test execution control method, apparatus, and system to at least solve the technical problem of how to securely implement managed control of the test lifecycle under the constraint that browser automation frameworks do not support cross-thread operations, enabling the web server to reliably pause, resume, and stop background test tasks, while ensuring that browser resources are not left behind when abnormally exiting.
[0008] According to one aspect of the embodiments of this application, a test execution control method is provided, comprising: starting a worker thread to execute a test task, wherein the worker thread calls a wait method of a thread event object before each test step during execution: if the thread event object is not triggered, it blocks and waits; if it has been triggered, it checks a stop flag, and the worker thread terminates the test when the stop flag is true; when a stop request is received, it determines whether the current caller is the worker thread: if yes, the current caller sets the stop flag and closes the browser resources; if no, the current caller first triggers the thread event object, then sets the stop flag, and the worker thread closes the browser resources automatically after detecting the stop flag.
[0009] Optionally, the worker thread is a daemon thread that terminates automatically when the main thread exits.
[0010] Optionally, the thread event object is initialized to a triggered state; when a pause request is received, the thread event object is cleared to a non-triggered state; when a resume request is received, the thread event object is triggered.
[0011] Optionally, it also includes: setting the test state to an idle state during initialization; setting the test state to a running state after starting the worker thread; setting the test state to a paused state when a pause request is received; setting the test state to a running state when a resume request is received; setting the test state to a stopped state when the stop flag is true; and setting the test state to a completed state when the test is completed normally.
[0012] Optionally, it also includes: registering operating system signal handling functions and process exit hooks to perform browser resource cleanup when the process exits abnormally.
[0013] Optionally, after the worker thread resumes from the blocked wait, it immediately checks the stop flag. If the flag is true, the worker thread performs the stop test and closes the browser resources automatically.
[0014] Optionally, after the worker thread starts, a browser persistent context is established, and the automatic closure of browser resources includes closing the browser instance and releasing the browser instance's persistent context.
[0015] Optionally, the stop request, pause request, and resume request are received via a web interface; the worker thread updates the current step information after each test step is executed, so that the execution progress can be obtained externally via the web interface.
[0016] According to another aspect of the embodiments of this application, a test execution control device is provided, comprising: a thread management module configured to start a worker thread to execute a test task; a pause control module configured to control the blocking, waiting, and resumption of the worker thread through a thread event object, wherein the worker thread calls the waiting method of the thread event object before each test step: if the thread event object is not triggered, it blocks and waits; if it is triggered, it checks a stop flag; a stop control module configured to determine whether the current caller is the worker thread when a stop request is received: if yes, it sets the stop flag and closes browser resources; if no, it first triggers the thread event object, then sets the stop flag, and the worker thread closes browser resources automatically after detecting the stop flag; and a state management module configured to stop the test by the worker thread when the stop flag is true.
[0017] According to another aspect of the embodiments of this application, a test execution control system is provided, including: the test execution control device as described above; a web server configured to receive stop requests, pause requests and resume requests through a web interface, and provide an HTTP polling interface for external access to the execution progress; a browser automation framework configured to perform browser operations in the worker thread; and a resource protection module configured to register operating system signal processing functions and process exit hooks, and trigger the stop control module to perform resource cleanup when the process exits abnormally.
[0018] Compared with the prior art, this application has the following beneficial effects: (1) By using the delegated closure mode, under the constraint that the browser automation framework does not support cross-thread operations, the safe closure request of the external thread to the browser resources is realized, thus avoiding the framework exception caused by cross-thread closure.
[0019] (2) The pause is achieved by using the blocking wait of the thread event object. During the pause, the CPU consumption is zero, which reduces the system resource consumption compared with the polling check flag.
[0020] (3) The signal transmission strategy of first unblocking the pause and then setting the stop flag solves the problem that the paused thread cannot respond to the stop request and ensures the timeliness of the stop operation.
[0021] (4) The multiple protection mechanisms of signal processing and exit hooks reduce the risk of browser zombie process residue when abnormally exiting and improve the robustness of the test service.
[0022] (5) The test engine service is made into a persistent web service, providing remote control and progress monitoring capabilities through the HTTP interface, so that non-technical personnel can also operate the test process through a browser. Attached Figure Description
[0023] To more clearly illustrate the technical solutions in the embodiments of this application or the prior art, the accompanying drawings used in the description of the embodiments or the prior art will be briefly introduced below. Obviously, the accompanying drawings described below are only some embodiments of this application. For those skilled in the art, other embodiments can be obtained based on these drawings without creative effort.
[0024] Figure 1 A flowchart of the test execution control method provided in the embodiments of this application; Figure 2 This is an overall structure diagram of the managed test execution engine system provided in an optional embodiment of this application; Figure 3 A flowchart of a test execution control method provided in an optional embodiment of this application; Figure 4 A flowchart for determining the delegated closure mode provided in an optional embodiment of this application; Figure 5 The signal transmission timing diagram for the stop pause state test provided in an optional embodiment of this application is shown. Detailed Implementation
[0025] Embodiments of this application will now be described in more detail with reference to the accompanying drawings. While some embodiments of this application are shown in the drawings, it should be understood that embodiments of this application can be implemented in various forms and should not be construed as limited to the embodiments set forth herein. Rather, these embodiments are provided to provide a more thorough and complete understanding of the embodiments of this application. It should be understood that the accompanying drawings and embodiments are for illustrative purposes only and are not intended to limit the scope of protection of this application.
[0026] To facilitate understanding of this application, some nouns or terms appearing in the description of the embodiments of this application shall be interpreted as follows: Thread event object: A thread synchronization primitive provided by the operating system, with two states: triggered and not triggered. It supports thread blocking and waiting and being awakened by other threads, and is used to achieve a pause with zero CPU consumption.
[0027] Delegated shutdown mode: a resource cleanup strategy where an external thread only marks the intention to stop and unblocks, and the worker thread closes the browser resources at the checkpoint, thus satisfying the restrictions of non-thread-safe frameworks.
[0028] Checkpoint: A control point set by the worker thread before the start of each test step to check for pause or stop conditions.
[0029] Persistence Context: A runtime mode that persists browser session data to disk, supporting the reuse of login state across test tasks.
[0030] Non-thread-safe automation frameworks: Frameworks that require all operations of a browser instance to be executed in the thread in which it was created, such as Playwright.
[0031] The wait method is a synchronization primitive provided by the thread's event object. When a thread calls this wait method, if the event object is currently in a triggered state, the method returns immediately; if the event object is in a non-triggered state, the current thread is suspended (blocked) by the operating system kernel until another thread sets the event object to a triggered state, at which point the thread is awakened and returns. During this process, the thread does not consume CPU time slices.
[0032] Stop Flag: A thread-safe Boolean variable (typically protected by atomic operations or locks) used to indicate whether the test should terminate. This flag is set by the stop control module and read by the worker thread at each checkpoint. When the stop flag is true, the worker thread aborts the test and closes the browser resources itself.
[0033] According to one aspect of the embodiments of this application, a test execution control method is provided, wherein the test engine executes the start, pause, resume and stop control of test tasks according to the following process, which is applicable to the lifecycle hosting and concurrency control scenarios of Web application automated testing. Figure 1 A flowchart of the test execution control method provided in the embodiments of this application is shown below. Figure 1 As shown, the method includes the following steps: Step S102: Start the worker thread to execute the test task. During the execution process, the worker thread calls the wait method of the thread event object before each test step: if the thread event object is not triggered, it blocks and waits; if it has been triggered, it checks the stop flag. When the stop flag is true, the worker thread stops the test.
[0034] Optionally, the engine first starts a worker thread, which is responsible for executing the specific automated test tasks. During the execution of the test tasks, the worker thread sets a checkpoint before each test step. At each checkpoint, the worker thread calls the wait method of the thread event object. At this point, a branch is generated based on the state of the thread event object: If the thread event object is in an untriggered state (i.e., has been cleared), the worker thread will enter a blocked waiting state, pausing the execution of subsequent test steps. This blocking is implemented by the operating system kernel; during the blocking period, the worker thread does not occupy CPU time slices, and system resource consumption is zero.
[0035] If the thread event object is in a triggered state, the wait method will return immediately, the worker thread will continue execution, and then check a global stop flag. If the stop flag is true (indicating that an external request has been made to stop the test), the worker thread will immediately terminate the entire test process and will no longer execute the current step or any subsequent steps; if the stop flag is false, the worker thread will execute the current test step normally.
[0036] Step S104: When a stop request is received, determine whether the current caller is a worker thread: if yes, the current caller sets the stop flag and closes the browser resources; if no, the current caller first triggers the thread event object, then sets the stop flag, and the worker thread detects the stop flag and closes the browser resources automatically.
[0037] Optionally, the engine receives stop requests from external sources via a web interface (e.g., a user clicking the "Stop" button on the front end). When a stop request is received, the engine first determines the thread identity of the current caller, i.e., whether the thread handling the request is itself. Based on the determination result, different processing branches are executed: If the current caller is the worker thread itself (for example, the worker thread actively requests to stop after detecting an unrecoverable error), then the current caller directly performs the stop operation: sets the stop flag to true, then immediately closes browser resources (including browser processes, page objects and their occupied network ports and temporary files), and finally exits the test execution loop.
[0038] If the current caller is another thread (such as the main thread or request processing thread of a web service, rather than a worker thread), the current caller does not directly close the browser. Instead, it performs two steps: first, it triggers the thread event object (setting it to the triggered state) to release any potential blocking or waiting by the worker thread; then, it sets the stop flag to true. After completing these two steps, the current caller returns immediately without performing any browser closing operation. The actual closing of browser resources is completed by the worker thread in a subsequent checkpoint: after being awakened by the triggered event, the worker thread will detect that the stop flag is true at the checkpoint, and then the worker thread will call the browser instance's close method to release all related resources.
[0039] The above order of "triggering the event object first, then setting the stop flag" ensures that even if the test is currently paused (the worker thread is blocked on the event object), the stop request will first unblock the worker thread, allowing the worker thread to see the stop flag and thus promptly execute the termination and cleanup. If the order is reversed (setting the flag first, then triggering the event), the worker thread will not see the stop flag during the blocking period, and the stop request will fail.
[0040] In step S102, a thread event object blocking mechanism is used to achieve pause, during which the worker thread does not consume any CPU time slices. Simultaneously, in step S104, the stop request in the paused state is handled in the order of "triggering the event first, then setting the flag," ensuring that the blocked worker thread can be promptly awakened and aware of the stop request. The combination of these two methods avoids CPU idling caused by polling the flag bit and solves the technical problem of stop requests not being responded to in the paused state.
[0041] Mainstream browser automation frameworks (such as Playwright) require that browser instances must be shut down in the thread that created them. Step S104 determines the browser's shutdown based on thread identity; it only closes directly if the caller is a worker thread. If the caller is another thread, it only sets a stop flag and unblocks, ultimately allowing the worker thread to shut it down automatically. This delegated shutdown pattern decouples the "marking of the stop intent" from the "execution of resource cleanup," fundamentally avoiding framework anomalies or resource leaks caused by cross-thread shutdown.
[0042] Whether the test is running or paused, stop requests are processed quickly. In the running state, worker threads check the stop flag before each test step, responding with a maximum delay of one test step. In the paused state, because an event is triggered to unblock the process, worker threads are awakened and immediately check the stop flag and abort the test; the response delay is only the time required for awakening and checking (in microseconds). Compared to the problem of stop failure in paused states in existing technologies, this solution significantly improves the timeliness and reliability of stop control.
[0043] Whether the worker thread closes the browser due to normal test completion (all steps executed) or actively closes the browser due to the detection of a stop flag, it follows the principle of "whoever creates it closes it." This concentrates the resource cleanup logic within the worker thread, facilitating maintenance and debugging, and also provides a clear foundation for subsequent expansion of resource protection mechanisms (such as signal handling hooks).
[0044] Because browser resources can be reliably closed, the testing platform avoids issues such as port congestion, memory leaks, and user data directory locking caused by residual browser processes. Operations personnel do not need to manually clean up residual processes, significantly improving the stability of continuous test task execution, making it particularly suitable for long-running, high-concurrency enterprise-level testing service scenarios.
[0045] In some embodiments, worker threads are daemon threads that terminate automatically when the main thread exits.
[0046] Optionally, when starting a test task, the test engine creates a thread object using the thread library, sets the thread's daemon flag to True, and then starts the thread to execute the test task. The lifecycle of this daemon thread is bound to the main thread (i.e., the main thread of the web service process). Once the main thread terminates due to normal exit, user interruption (such as pressing Ctrl+C), or a termination signal sent by the operating system, the daemon thread will be automatically terminated by the runtime environment without explicitly calling a wait method or sending an additional stop command.
[0047] In conventional web services, if worker threads are not daemon threads, they may continue running even after the main thread receives an exit signal, leading to incomplete process exit or the creation of zombie threads. In this embodiment, by setting daemon threads, worker threads automatically terminate when the main thread exits, avoiding thread remnants. Furthermore, there is no need to explicitly wait for worker threads to complete or forcibly terminate them at the end of each test, reducing code complexity. This is particularly suitable for long-running test tasks; when the service needs to be quickly restarted or upgraded, daemon threads will not become an obstacle.
[0048] The daemon thread in this application addresses the issue of automatic thread termination in scenarios of "normal / controlled process exit"; while the signal handling function and process exit hook are used to actively clean up external resources such as the browser process. The combination of these two ensures that the worker thread itself does not remain, and also ensures that sub-resources such as the browser instance are correctly released.
[0049] In some embodiments, the thread event object is initialized to a triggered state; when a pause request is received, the thread event object is cleared to an untriggered state; when a resume request is received, the thread event object is triggered.
[0050] Optionally, the thread event object is used as a pause / resume control signal for the test execution flow. Specifically, during test engine initialization, the thread event object is created and set to the triggered state (i.e., triggered, set state). This means that when the worker thread first executes to the checkpoint before each test step, since the event object is already in the triggered state, the wait method will return immediately, the worker thread will not be blocked, and the test task will proceed normally.
[0051] When the test engine receives a pause request from the user via the web interface, it calls the clear method of the event object, setting the event object to an untriggered state (i.e., cleared). At this point, when the worker thread completes the current test step and is at the checkpoint before proceeding to the next, it calls the wait method of the event object. Since the event object is untriggered, the worker thread enters a blocked wait state, pausing test execution. Because this blocking is implemented using an operating system kernel-level event object, the worker thread does not occupy CPU time slices during the blocking period, resulting in zero system resource consumption.
[0052] When a user sends a recovery request via the web interface, the engine calls the event object's trigger method, resetting the event object to the triggered state. At this point, the worker threads that were previously blocked on the waiting method are immediately awakened and continue executing subsequent test steps, thus resuming the test process.
[0053] During test execution, the engine does not require any polling mechanism to check whether a pause is needed; zero-cost waiting is achieved entirely through the blocking characteristics of event objects. Furthermore, the triggering and clearing operations of event objects are atomic operations, requiring no additional lock synchronization mechanisms.
[0054] In this embodiment, a kernel-level thread event object is used to implement blocking and waiting. Compared with the common method of polling and checking the pause flag in the prior art, the worker thread does not consume any CPU time slices during the pause. In scenarios with long pauses (such as waiting for manual confirmation of environmental conditions), the system load is significantly reduced, which is especially suitable for test environments with multiple concurrent test tasks or limited resources.
[0055] The triggering and clearing of event objects can immediately change the blocked state of waiting methods, eliminating the check interval delay found in polling methods. Pause requests can be responded to instantly at the next checkpoint, and resume requests can wake up worker threads within microseconds, ensuring real-time test control.
[0056] Event objects, as standard synchronization primitives provided by the operating system, are inherently thread-safe in their triggering / cleaning operations, requiring no additional locks or atomic variables. Compared to polling flags, which requires memory barriers or locks to ensure multi-threaded visibility, this approach is simpler to implement and more reliable.
[0057] The triggering state of the event object is used not only for pause / resume but also for coordinating stop requests. When a test is paused (event not triggered) and a stop request is received, the engine first triggers the event to unblock it, then sets the stop flag, enabling worker threads to promptly detect the stop request and perform resource cleanup. This coordination allows the pause, resume, and stop control commands to work in unison under the same synchronization mechanism, avoiding conflicts between multiple signal sources.
[0058] The event object is initialized to the triggered state by default, so that the worker thread can be executed directly after the test starts without any additional operation. There is no need for special handling or setting of initial flags at startup, which reduces code complexity.
[0059] Since the CPU is not occupied during the pause, the test platform can run multiple test instances simultaneously on the same physical machine or virtual machine. Each instance can be paused independently without affecting each other, which improves the utilization of hardware resources and reduces the deployment and maintenance costs of the test platform.
[0060] In some embodiments, the test state is further defined as follows: during initialization, the test state is set to an idle state; after the worker thread is started, the test state is set to a running state; when a pause request is received, the test state is set to a paused state; when a resume request is received, the test state is set to a running state; when the stop flag is true, the test state is set to a stopped state; and when the test is completed normally, the test state is set to a completed state.
[0061] Optionally, the test engine internally maintains a finite state machine to represent the stage of the test task in its current lifecycle. The state machine defines five mutually exclusive test states: idle, running, paused, stopped, and completed, and specifies the rules for legal transitions between states.
[0062] During test engine initialization, the test state is set to idle, indicating that there are no test tasks currently being executed or waiting to be executed. When a user initiates a test request through the web interface, the engine creates a worker thread and starts the test task. At this point, the test state changes from idle to running, indicating that the test is executing normally.
[0063] If a user sends a pause request while the test is running, the engine will change the test status to paused, indicating that the test is paused and awaiting resumption. If the user sends a resume request, the engine will change the test status back from paused to running, and the test will continue execution.
[0064] If a user sends a stop request while the test is in the running or paused state, the engine will change the test status to the stopped state, indicating that the test has been actively terminated by the user. Conversely, if a worker thread successfully executes all test steps without receiving a stop request, the engine will change the test status from running to completed, indicating that the test has successfully ended.
[0065] During state transitions, the engine checks whether the current state allows the target transition. For example, an idle state cannot be directly transitioned to a paused state, and a completed state cannot be transitioned back to a running state. Any illegal transition request will be rejected, and the corresponding error log will be logged or a failure response will be returned to the frontend.
[0066] The test status can be stored in a global variable of the engine instance and updated through thread-safe write operations (such as locking or atomic assignment) to ensure that the front end reads a consistent value when polling for the status in a multi-threaded environment.
[0067] In this embodiment, the state machine exposes the execution progress of the test task in the form of discrete states. The front-end or monitoring system can obtain the current state through simple polling without parsing complex test logs or executing intermediate data. This design makes the testing process transparent to the user, enhancing the observability and maintainability of the test service.
[0068] Based on the state machine's valid transition rules, the engine can automatically reject invalid control commands in the current state. For example, if a user sends a pause request after a test has been completed or stopped, it will be rejected; a stop request sent in an idle state will also be ignored. This avoids abnormal behavior or incorrect resource release caused by invalid operations, improving the system's robustness.
[0069] Existing technologies often conflate user-initiated termination with normal test completion, failing to distinguish between interrupted and successful test termination. This solution addresses this by setting two distinct final states: "stopped" and "completed," enabling test reports to accurately record the reason for test termination (whether user termination or normal completion), facilitating subsequent analysis and auditing.
[0070] The explicit state signals provided by the state machine can serve as conditions to trigger other automated processes. For example, a test report email can be automatically sent when the state changes to "complete," and temporary data can be automatically cleaned up when the state changes to "stopped." This integration capability expands the application scenarios of the test engine as a service platform.
[0071] State machine management, as an independent monitoring layer, does not interfere with the core control logic described in the independent control layer, such as thread event object blocking and delegate closing. This layered design allows state information to be added or modified at any time without affecting the correctness of test execution, reduces system coupling, and facilitates subsequent functional expansion.
[0072] In some embodiments, the method further includes: registering operating system signal handling functions and process exit hooks to perform browser resource cleanup when the process exits abnormally.
[0073] Optionally, the test engine registers two types of resource cleanup mechanisms at startup to ensure that the browser process will not remain in the extreme case of abnormal process termination.
[0074] The first category is operating system signal handling functions. The engine registers signal handling functions via system calls to capture interrupt and termination signals sent by the operating system to the process. When a user presses a key combination on the terminal or an administrator sends a termination signal via process management tools, the operating system delivers the corresponding signal to the process. Once the signal handling function registered by the engine is triggered, it immediately executes the browser resource cleanup process: first, it sets the engine's internal stop flag to true, then it forcibly closes the browser instance started by the automation framework (including the main browser window, related rendering processes, and child pages). After cleanup is complete, the signal handling function calls the process exit function to terminate the current process.
[0075] The second type is the process exit hook. The engine registers an exit callback function through a process exit hook registration mechanism (such as the `atexit` function in the C standard library). Regardless of whether the process exits normally, exits abnormally, or exits after signal handler cleanup, this hook function will be automatically called by the system in the final stages before the process terminates. The hook function also includes mandatory cleanup logic for browser resources, serving as a fallback to the signal handler. If the signal handler fails to execute completely for some reason (such as being interrupted by a second signal or encountering an exception during execution), the exit hook still has a chance to attempt to release browser resources again before the process terminates.
[0076] The execution order of the two mechanisms is as follows: when an abnormal exit occurs, the signal handling function responds first, performing the first cleanup; then the process exit hook acts as a second line of defense, performing the second cleanup (even if the first cleanup is successful, calling the shutdown method again is usually an idempotent operation and will not produce side effects). If the process is forcibly terminated by the operating system and cannot execute any code (such as by an uncaught signal), neither mechanism will work. However, this is an extreme scenario, and in actual operation and maintenance, it can be handled separately through external monitoring methods such as watchdog processes.
[0077] Browser processes launched by browser automation frameworks typically run independently of test processes. When a test process crashes or is forcibly terminated due to an exception, conventional finally blocks or context managers fail to execute, easily turning the browser process into an orphan or zombie process that continuously consumes system memory and network ports. This solution elevates resource cleanup from the application layer to the system layer through operating system-level signal handling and process exit hooks, significantly reducing the risk of browser remnants.
[0078] Signal handling functions can respond promptly to external termination signals, completing cleanup before the process is destroyed; process exit hooks cover exit paths that signal handling functions might miss (such as uncaught exceptions or direct calls to the process exit function). The combination of these two mechanisms ensures that even if one fails due to an exception, the other still has a chance to perform cleanup, forming a fault-tolerant design that is more robust than a single cleanup method.
[0079] When the browser closes in a signal handler or exit hook, the engine directly calls the forced close method without relying on thread identity checks in the delegated close mode, since the worker thread may no longer exist or be in an unknown state. This design ensures that resources are still released in extreme exit scenarios while maintaining the decoupling of the delegated close mode in normal scenarios.
[0080] Test services are typically deployed on servers and run long-term, and operations personnel may restart the service via system commands. If a browser process remains after each abnormal exit, operations personnel need to manually clean it up, increasing maintenance costs. This solution implements automatic cleanup, allowing test services to be started and stopped at will like ordinary web services, without the need for additional manual resource reclamation steps, thus reducing operational complexity.
[0081] Browser process remnants not only consume resources but can also cause subsequent tests to fail (e.g., port conflicts or locked user data directories). This solution reduces the probability of remnants, improving the success rate of the testing platform in executing multiple test tasks consecutively.
[0082] In some embodiments, after a worker thread resumes from a blocked wait, it immediately checks the stop flag. If the flag is true, the worker thread performs a stop test and closes the browser resources itself.
[0083] Optionally, the worker thread calls the wait method of the thread event object at the checkpoint before each test step. When the thread event object is in an untriggered state, the worker thread enters a blocked wait state, pausing test execution. When the external system unblocks the process by triggering the event object, the worker thread is awakened by the operating system. At this time, the worker thread does not immediately execute the next test step, but first checks the status of the stop flag.
[0084] After returning from the wait method, the worker thread immediately executes a conditional statement to read the current value of the stop flag. If the stop flag is false, it means no stop request has been received, and the worker thread continues executing the current test step. If the stop flag is true, it means an external request to stop the test has been received, and the worker thread immediately terminates the test process, skipping all subsequent unexecuted test steps. The worker thread then calls the browser instance's close method to release the browser process and related resources (including the user data directory, temporary files, network ports, etc.). Throughout this process, the worker thread does not perform any additional test operations and does not re-enter the checkpoint loop.
[0085] This "check immediately after wake-up" design ensures that stop requests receive the most timely response. Even if the stop request is issued just after the worker thread passes a checkpoint and before it begins executing a test step, as long as the stop request triggers the event object and sets the stop flag, the worker thread will immediately detect the stop flag and perform cleanup upon being woken up at the next checkpoint (or, if the worker thread is executing a step, it must wait until the next checkpoint after the step is completed). For stop requests in a paused state, since the external event object is triggered first to unblock the process and then the stop flag is set, the worker thread will definitely see the already set stop flag upon being woken up, thus reliably entering the aborted branch.
[0086] At the implementation level, the stop flag is typically a thread-safe boolean variable (e.g., protected by atomic operations or locking) to ensure that the value read by the worker thread is consistent with the value set by the external thread. The worker thread executes this check logic every time it resumes from a blocked wait, without the need for additional polling or timers.
[0087] In existing technologies, when a test thread is blocked on an event object due to a pause, the external stop request cannot be detected by the blocked thread. This embodiment forms a complete signal transmission chain by combining the external operation sequence of "first triggering the event to unblock, then setting the stop flag" with the internal behavior of the worker thread "checking the stop flag immediately after being woken up." Once the worker thread is woken up, its first action is to check the stop flag, ensuring that the stop request is processed with zero delay, avoiding stop delays or failures caused by executing other logic first after being woken up.
[0088] Browser automation frameworks typically require browser instances to perform shutdown operations within their creation thread. In this embodiment, the worker thread is both the thread that creates the browser instance and the thread that performs the shutdown operation upon detecting the stop flag. This design fundamentally avoids framework exceptions or resource leaks caused by closing the browser across threads, ensuring thread safety along the stop path.
[0089] Upon detecting the stop flag, the worker thread immediately terminates the test and closes the browser itself, refraining from executing subsequent test steps. This avoids exceptions caused by continuing browser operations (such as clicking or typing) while the browser is already stopped. Furthermore, as the sole owner of the browser instance, the worker thread performs the shutdown action only once, preventing race conditions where multiple threads contend to close the same browser.
[0090] When the test completes normally, the worker thread closes the browser after executing all steps, which is an orderly resource release; however, this embodiment describes the resource release under the stop path. Both follow the principle of "whoever creates it closes it", but the triggering conditions are different (stop flag is true vs. steps exhausted), making the test behavior predictable and facilitating problem localization and log analysis.
[0091] Because worker threads check the stop flag immediately after resuming from blocking, stop requests are responded to precisely at the first checkpoint after resumption, regardless of the pause duration (seconds or hours). Test behavior remains unchanged regardless of pause length, improving system determinism and contributing to the stability and reproducibility of automated tests.
[0092] In some embodiments, after a worker thread starts, it establishes a browser persistent context and automatically closes browser resources, including closing the browser instance and releasing the browser instance's persistent context.
[0093] Optionally, when starting a test task, the worker thread first establishes a browser persistent context. Specifically, the worker thread calls the persistent context interface provided by the browser automation framework (such as Playwright or Selenium), passing in a specified user data directory path. This directory is used to store persistent data for the browser session, including cookies, local storage (localStorage), IndexedDB, website permission settings, and logged-in status. After the persistent context is started, the worker thread creates a browser page instance within this context and executes subsequent automated test steps.
[0094] The state data of the persistent context is persisted to the user data directory on disk, rather than being stored only in memory. This means that all session information generated during test execution is retained even after the browser is closed. When the same or another test task starts the persistent context again using the same user data directory, the browser automatically loads the previously saved session state without requiring re-login or reconfiguration of website permissions, thus achieving session reuse across test tasks.
[0095] When a worker thread detects that the stop flag is true or the test has completed normally, it performs the operation of automatically closing browser resources. This operation consists of two levels: the first level is to close the browser instance itself, that is, to call the close method of the persistent context object to terminate the browser process and all its related child processes (such as the rendering process, GPU process, etc.); the second level is to release the persistent context of the browser instance. This step ensures that the user data directory is properly unlocked and that temporary files, lock files, and memory-mapped files associated with the persistent context are cleaned up to avoid failures when starting a new context using the same user data directory due to resource consumption.
[0096] It's important to note that releasing the persistent context does not equate to deleting the user data directory. Releasing the persistent context only disables the framework's exclusive access to the directory; session data within the directory (such as cookies and local storage) is fully preserved for reuse in subsequent test tasks. If the test scenario requires a completely new, clean browser environment for each test (without retaining any historical sessions), the engine can choose not to create a persistent context and instead create a regular non-persistent context. The persistent context solution provided in this embodiment is suitable for scenarios that require maintaining a login state or sharing session data across test tasks.
[0097] In traditional non-persistent browser testing, each test task requires performing preliminary steps such as login, navigation to the target page, and setting website permissions from scratch. These steps are often time-consuming and repetitive. This embodiment uses a persistent context to save the session state generated during the first test to disk, which is automatically loaded when subsequent test tasks start, eliminating the need to repeat time-consuming login and initialization operations. For regression test sets that need to be run frequently, the overall execution time can be reduced by several minutes or even tens of minutes, significantly improving testing efficiency.
[0098] The exclusive access of the persistent context to the user data directory requires that the shutdown operation must be performed by the thread holding the context (i.e., the worker thread). In this embodiment, the worker thread automatically shuts down the browser instance and releases the persistent context, which perfectly meets this requirement. If an external thread forcibly closes the browser, the persistent context may not be released properly, resulting in corrupted or inconsistent files in the user data directory, preventing subsequent tests from starting. This solution, through a delegated shutdown mode, fundamentally ensures the security and data integrity of the persistent context release.
[0099] This embodiment does not mandate the use of persistent contexts for all tests. The engine can dynamically choose whether to enable persistent contexts based on the needs of the test task: for test cases that require isolating test data or verifying first-access behavior, persistent contexts may not be necessary; for long-process test cases that require maintaining login status, persistent contexts can be enabled. This flexibility expands the applicability of the test engine, enabling it to be compatible with various test scenarios without modifying the core control logic.
[0100] In traditional testing practices, to maintain a logged-in state, test scripts often need to hardcode usernames and passwords and repeatedly execute the login operation in each test module. This not only increases script complexity but also introduces the risk of password leakage. By using persistent context, a manual login is required only once during the first execution (or using a dedicated one-time login script). Subsequent test tasks can automatically reuse the logged-in state. The test script no longer needs to explicitly include login steps, thereby reducing the difficulty of script writing and maintenance while improving test security.
[0101] Once the test completes normally and the worker thread releases the persistent context, the state machine enters the "completed state," indicating that the test has successfully ended and the resources have been fully released. If an exception occurs during the release process (such as the user data directory being occupied by another process), the state machine can capture the exception and enter the exception handling path (such as logging errors), facilitating rapid problem location by operations and maintenance personnel. This design, combined with state machine management, enhances the system's observability and fault diagnosis capabilities.
[0102] In some embodiments, stop requests, pause requests, and resume requests are received via a web interface; worker threads update the current step information after each test step is executed, so that the execution progress can be obtained externally via the web interface.
[0103] Optionally, the test engine provides a web interface to receive control commands from the frontend and provide progress queries in the form of a RESTful API. Specifically, the test engine runs as a persistent web service, listening on a specific port. The frontend (such as a test management interface running in a browser) interacts with the engine by sending HTTP requests.
[0104] The control requests are received as follows: When the user clicks the "Start Test" button, the frontend sends a request to the start endpoint of the web interface. Upon receiving the request, the engine starts a daemon worker thread to execute the test task. During test execution, the frontend triggers the engine's pause, resume, or stop operations by sending HTTP requests to the pause, resume, or stop endpoints, respectively. Each control request contains necessary parameters (such as the test task identifier), and the engine invokes the corresponding control logic based on the request.
[0105] When a worker thread executes a test task, it maintains a variable containing information about the current step. This variable includes fields such as step number (e.g., which step), step description (e.g., "Click the login button"), and start timestamp. After each test step is completed, the worker thread updates this variable, writing the latest step information to thread-safe shared storage (e.g., an atomic reference in the engine instance or a lock-protected property). Since the worker thread is the only thread writing this information, and external reads can occur at any time, the write operation must guarantee visibility to external reads.
[0106] The execution progress is obtained externally as follows: The frontend calls the progress query endpoint of the web interface via a timed polling method (e.g., sending an HTTP request every 500 milliseconds). When processing this request, the engine reads the latest stored step information and encapsulates it into a JSON format response, returning it to the frontend. After parsing the response, the frontend displays the currently executing test step number and description on the interface in real time. The polling interval can be configured according to network conditions and real-time requirements, typically set between 200 milliseconds and 1000 milliseconds. Since the execution time of a test step is usually several seconds to tens of seconds, the polling method can provide near real-time progress updates, while its implementation complexity is far lower than full-duplex communication solutions such as WebSocket.
[0107] In addition, the web interface can return richer test status information, such as the overall test status (idle, running, paused, stopped, completed), the percentage of steps executed out of the total steps, and the estimated remaining time. This information is also updated by worker threads at appropriate times and is polled by the front end.
[0108] Traditional automated testing frameworks typically exist as command-line tools or IDE plugins, requiring users to have programming knowledge to start, pause, or view progress. This embodiment exposes test control capabilities and progress information to the browser frontend through a web interface, enabling product managers, test engineers, and even operations personnel to operate test tasks through a graphical interface without writing code. This significantly lowers the barrier to entry for automated testing and expands the user base of the testing service.
[0109] Because the web interface is based on the HTTP protocol, the testing engine can be deployed on a remote server, and users can access the testing service through any device with a browser (including tablets and mobile phones). This design extends testing capabilities from a single-machine environment to a team collaboration environment, supports multiple users concurrently operating different testing tasks, and provides infrastructure support for building an enterprise-level testing platform.
[0110] This embodiment uses HTTP polling to obtain progress, rather than implementing a push mechanism within the engine. The polling operation is completely independent of the core thread event object control logic and will not interfere with the blocking wait or stop flag checks of worker threads. Compared with long-connection solutions such as WebSocket, the polling method is simple to implement, requires no maintenance of connection state, and does not require the web framework to support asynchronous I / O, reducing the implementation difficulty and deployment requirements of the engine. Furthermore, since the test steps are updated at a low frequency (several times per second), the network overhead generated by polling is negligible.
[0111] The update information from worker threads is not only displayed in real time, but can also be logged or stored in a database. When a test fails or an exception occurs, developers can quickly locate the problem based on the last recorded update information, without having to reproduce the entire test process from scratch.
[0112] The state machine provides the test lifecycle states (such as running, paused, and stopped), while the step information provides execution details (such as which step is currently being executed and what the specific operation is). Combining the two, the front end can simultaneously display "Test is running" and "Executing step 8: Fill in the form," making the user's perception of the test progress more accurate and comprehensive, thus improving the user experience.
[0113] In multi-tasking scenarios (where the engine runs multiple test tasks simultaneously), each task corresponds to a worker thread and independent storage of step information. The web interface can return the progress of the corresponding task based on the task identifier in the request parameters. This allows the testing platform to support multiple users or the same user running multiple test suites simultaneously, with the progress of each task not interfering with each other, meeting the needs of enterprise-level concurrent testing.
[0114] Figure 2 A general structural diagram of the managed test execution engine system provided in an optional embodiment of this application is shown below. Figure 2 As shown, the managed test execution engine provided in this embodiment adopts a global singleton pattern, ensuring that only one instance is created in a multi-threaded environment through double-checked locking. This engine includes the following modules: The state machine module is used to maintain the five states of the test lifecycle: IDLE, RUNNING, PAUSED, STOPPED, and COMPLETED, and to control the legal transitions between states.
[0115] The pause control module is implemented based on the thread event object provided by the operating system. This module provides wait, cleanup, and trigger methods. Before executing each test step, the worker thread calls the wait method. If the event object has not been triggered, the thread blocks and waits, consuming zero CPU; if it has been triggered, execution continues.
[0116] The stop control module is used to implement the delegated shutdown mode. When a stop request is received, this module determines the thread identity of the current caller: if the caller is a worker thread, it directly sets the stop flag and closes the browser resources; if the caller is another thread, it first triggers an event object to remove any possible blocking, then sets the stop flag, and the worker thread closes the browser resources itself.
[0117] The delegated shutdown module (which can be merged with or stand alone from the stop control module) specifically implements the decoupled logic of thread identity determination and resource cleanup mentioned above, ensuring that the browser instance is always shut down in the thread that created it.
[0118] The resource protection module is used to register operating system signal handling functions (such as SIGINT and SIGTERM) and process exit hooks (atexit). When a process exits abnormally, this module triggers the stop control module to perform forced cleanup of browser resources, preventing browser process remnants.
[0119] The progress reporting module allows worker threads to write the current step number and description to a thread-safe shared variable after executing each test step. External systems can then obtain the real-time execution progress through this module.
[0120] The web interface module provides a set of RESTful APIs, including interfaces for starting, pausing, resuming, stopping, and querying progress. The frontend calls the progress query interface via HTTP polling to obtain the current step information and displays it on the user interface.
[0121] Internally, test tasks are executed as daemon threads. The web frontend interacts with the web interface module via HTTP requests. The web interface module calls the pause control module, stop control module, and other corresponding interfaces to control the background worker threads. During execution, the worker threads update step information in real time through the progress reporting module, which is then polled by the frontend. The resource protection module is independent of the above control flow, registering at system startup as a fallback cleanup mechanism.
[0122] After receiving a request from the frontend, the Web interface module calls the pause control module or the stop control module. The pause control module controls the blocking and waking of worker threads through event objects. The stop control module controls the termination behavior of worker threads through stop flags and delegate shutdown logic. When worker threads execute test steps, they drive browser instances through the browser automation framework and provide progress information to the outside world through the progress reporting module. When the process is abnormal, the resource protection module directly calls the cleanup interface of the stop control module.
[0123] Figure 3 A flowchart of the test execution control method provided in an optional embodiment of this application is shown below. Figure 3As shown, the test execution control method provided in this embodiment includes the following steps: Step S301: The test engine starts the worker thread and initializes the thread event object to the triggered state, and initializes the stop flag to false.
[0124] Step S302: The worker thread begins executing the test task and enters the main loop. Before each test step is executed, the worker thread first calls the wait method of the thread event object.
[0125] Step S303: Determine whether the thread event object is in a triggered state. If the event object is not triggered (i.e. has been cleared), proceed to step S304; if the event object is triggered, proceed to step S305.
[0126] Step S304: The worker thread enters a blocked waiting state, pausing test execution. This blocking is implemented by the operating system kernel, during which the worker thread does not consume CPU time slices. When an external call to resume operation triggers the event object, the thread is awakened and then returns to step S303 for re-examination.
[0127] Step S305: The worker thread checks the stop flag. If the stop flag is true, proceed to step S306; if the stop flag is false, proceed to step S307.
[0128] Step S306: The worker thread terminates the test process and automatically closes browser resources (including browser processes, page objects, and related temporary files), and then terminates the thread.
[0129] Step S307: The worker thread executes the current test step, driving the browser to complete tasks such as page operations and data collection through the browser automation framework.
[0130] Step S308: After completing the current test step, the worker thread updates the progress information (such as the current step number and step description) for external users to obtain via a web interface.
[0131] Step S309: Determine if there are any unexecuted test steps. If there are still subsequent steps, return to step S302 and enter the next checkpoint loop; if all steps have been executed, proceed to step S310.
[0132] Step S310: The test is completed normally. The worker thread closes the browser resources, sets the test status to complete, and terminates the thread.
[0133] In the above process, steps S303 to S306 constitute the core control loop. The handling of external stop requests can influence the judgment results of steps S303 and S305 by modifying the event object state and the stop flag. For example, when a user sends a pause request, the engine clears the event object (setting it to untriggered), and the worker thread enters a blocked waiting state at step S303 (step S304), thus pausing. When a user sends a resume request, the engine triggers the event object, the worker thread is awakened in step S304, and then step S303 determines that it has been triggered and continues execution. When a user sends a stop request, if the current caller is an external thread, the engine first triggers the event object (ensuring the worker thread is not in a blocked state), and then sets the stop flag to true. After the worker thread passes the check in step S303, it detects that the stop flag is true in step S305 and enters step S306 to perform termination and cleanup. If the stop request is initiated by the worker thread itself, the engine directly sets the stop flag and closes the browser.
[0134] Figure 4 A flowchart for determining the delegated closure mode provided in an optional embodiment of this application is shown below. Figure 4 As shown, the delegated shutdown mode provided in this embodiment is used to handle requests from external threads to close browser resources. When the test engine receives a request to close browser resources via a web interface or other means, it executes the following judgment process: Step S401: Receive a request to close browser resources. This request may originate from the worker thread itself (e.g., self-cleaning after a test completes normally or a stop flag is detected) or from an external thread (e.g., the web request processing thread responding to the user's stop operation).
[0135] Step S402: Determine whether the current caller's thread identity is a worker thread. Specifically, the engine obtains the thread identifier of the currently executing request and compares it with the pre-saved worker thread identifier. If they are the same, the current caller is determined to be a worker thread, and step S403 is executed; if they are different, it is determined to be an external thread, and step S404 is executed.
[0136] Step S403: The current caller is a worker thread. At this point, the worker thread directly performs the browser resource closing operation, including calling the browser instance's close method, releasing the persistent context, terminating the browser process and its child processes, and cleaning up temporary files. After closing is complete, the process ends.
[0137] Step S404: The current caller is an external thread (such as a web request processing thread). At this point, the engine does not directly close the browser resources, but instead executes the delegated shutdown logic: First, it triggers the thread event object (setting it to the triggered state) to release any potential blocking or waiting by the worker thread; second, it sets the stop flag to true, marking the intention to stop. After completing these two steps, the external thread immediately returns without performing any browser shutdown operation.
[0138] Step S405: During its subsequent execution (e.g., at checkpoints before each test step), the worker thread detects that the stop flag is true. The worker thread then automatically performs the browser resource shutdown operation, including closing the browser instance and releasing the persistent context. At this point, the delegated shutdown process is complete.
[0139] The core of the delegated shutdown pattern described above lies in decoupling the "marking of the stop intent" from the "execution of resource cleanup." Regardless of which thread the shutdown request originates from, the browser instance is always shut down by the worker thread that created it, thus completely circumventing the browser automation framework's prohibition on cross-thread operations. When the request comes from an external thread, that thread is only responsible for passing the stop signal and unblocking any potential obstructions, without directly touching the browser object, avoiding framework exceptions or resource leaks caused by cross-thread calls.
[0140] Figure 5 The signal transmission timing diagram for the stop pause state test provided in the optional embodiments of this application is as follows: Figure 5 As shown, this embodiment provides a signal transmission timing for handling stop requests when the test is paused, demonstrating the interaction order between external threads (such as the Web request processing thread), thread event objects, stop flags, and worker threads.
[0141] The sequence diagram includes the following participants: External thread: the web service thread that handles user stop requests, a non-worker thread; Thread event object: a synchronization primitive used to implement pause / resume, initially in an untriggered state (corresponding to the test pause state); Stop flag: a global boolean variable, initially false; Worker thread: the thread that executes test tasks, currently in a blocked waiting state (paused because the event object has not been triggered).
[0142] Furthermore, the signal transmission timing includes the following steps: Step T1: The user clicks the "Stop" button on the front end, the web server receives the stop request, and an external thread begins processing it.
[0143] Step T2: The external thread first calls the trigger method (set) of the thread event object, setting the event object from an untriggered state to a triggered state. At this point, the worker thread that was originally blocked on the event object's waiting method is awakened by the operating system kernel.
[0144] Step T3: The worker thread resumes from the blocked state, exits the waiting method, and prepares to continue execution. At this point, the worker thread has not yet checked the stop flag.
[0145] Step T4: The external thread then sets the stop flag to true, marking the intention to stop. Note that this step is performed after the event object is triggered, ensuring the correct order: if the order is reversed (setting the flag first and then triggering the event), the worker thread will not be able to detect the stop flag because it is still in a blocked state.
[0146] Step T5: The worker thread executes the stop flag check logic at the checkpoint. Since the stop flag was set to true in step T4, the worker thread detects that the stop flag is true.
[0147] Step T6: The worker thread terminates the test process based on the detection results and automatically calls the browser instance's close method to release browser resources (including browser process, persistent context, network port, and temporary files).
[0148] Step T7: After the worker thread completes resource cleanup, the thread terminates. At this point, the stop request processing is complete.
[0149] The above timing design solves the technical problem in existing technologies where stop requests cannot be responded to when testing is paused. By first unblocking the worker thread, allowing it to enter the checkpoint execution logic, and then setting a stop flag so that the checkpoint can detect the stop intention, timely response to stop requests and safe release of resources are guaranteed.
[0150] Example 1: User pauses and resumes test scenario A user initiates a 20-step automated test for a web application via a web frontend. Upon reaching step 8, the user clicks the "Pause" button. The web server receives the pause request, calls the controller's pause method, and clears the event object. After completing step 8, the worker thread enters a checkpoint before step 9, calling the event object's wait method, causing the thread to block and CPU consumption to drop to zero. The user then observes the status as "Paused" through the frontend, confirms certain environmental conditions, and clicks "Resume." The controller triggers the event object, waking the worker thread from its blocking state, and it continues execution from step 9 until all steps are completed.
[0151] Example 2: Scenario where the user stops the test while it is paused. The user starts the test, pauses it, and then decides to stop the test completely. Upon receiving the stop request, the web server controller executes the following steps: first, it triggers an event object to unblock the pause; then, it sets the stop flag to true; and finally, it calls the method to force-close the browser. Since the current caller is the web request processing thread, not a worker thread, the delegated shutdown mode does not directly close the browser but only logs the changes. After the worker thread resumes from blocking, it finds the stop flag is true at a checkpoint, aborts the test process, and the worker thread automatically closes the browser instance and releases its resources.
[0152] Example 3: Resource cleanup scenario for abnormal process termination During service testing, operations personnel terminated the service process using Ctrl+C. The operating system sent a SIGINT signal to the process, triggering the registered signal handler, which then executed a cleanup process: first, the controller's stop method was called to mark the intention to stop, and then the method to force-close the browser was called. If the signal handler failed to execute completely (e.g., interrupted by a secondary signal), an exit hook registered with atexit served as a fallback, attempting to close the browser instance again before the process exited. This dual mechanism ensured that the browser process did not become a zombie process remaining in the system.
[0153] According to another aspect of the embodiments of this application, a test execution control device is provided. This device is deployed as a software module within a test engine to manage the lifecycle of test tasks. The device includes a thread management module, a pause control module, a stop control module, and a state management module. These modules work collaboratively, as detailed below: The thread management module is configured to start worker threads to execute test tasks.
[0154] The thread management module is responsible for starting and monitoring worker threads. When a user initiates a test request through the front end, the thread management module creates a new worker thread (usually set as a daemon thread) and assigns the test task to that thread for execution. After the worker thread starts, it executes each step of the test case sequentially, interacting with the pause control module before each step begins and maintaining communication with the state management module during step execution. The thread management module is also responsible for logging error information and notifying other modules to perform resource cleanup when a worker thread exits abnormally.
[0155] The pause control module is configured to control the blocking, waiting, and resumption of worker threads through a thread event object. Before each test step, the worker thread calls the wait method of the thread event object: if the thread event object has not been triggered, it blocks and waits; if it has been triggered, it checks the stop flag.
[0156] The pause control module internally maintains a thread event object, providing two interfaces: pause and resume. When the user clicks pause, the pause control module calls the event object's clear method, setting it to an untriggered state; when the user clicks resume, it calls the event object's trigger method, setting it to a triggered state. Before executing each test step, the worker thread calls the wait method provided by the pause control module, which directly calls the wait primitive of the thread event object. If the event object is untriggered, the worker thread enters a blocked wait state, pausing test execution; if the event object is triggered, the wait method returns immediately, and the worker thread continues execution. During the waiting period, the worker thread does not consume CPU time slices. The pause control module is also responsible for initializing the event object to a triggered state, ensuring that the test does not pause by default after startup.
[0157] The stop control module is configured to determine whether the current caller is a worker thread when it receives a stop request: if yes, it sets a stop flag and closes the browser resources; if no, it first triggers the thread event object, then sets the stop flag, and the worker thread closes the browser resources automatically after detecting the stop flag.
[0158] The stop control module handles stop requests sent externally (usually via a web interface). Upon receiving a stop request, the stop control module first determines the caller's thread identity: if the caller is the worker thread itself (e.g., the worker thread detects a fatal error and stops voluntarily), the stop control module directly performs two actions: setting a global stop flag to true, and then calling the browser instance's close method to release all related resources (including the browser process, page object, network port, and temporary files). If the caller is another thread (such as a web request processing thread), the stop control module executes sequentially: first, it calls the pause control module's trigger method to set the thread event object to the triggered state, thus releasing any potential blocking or waiting by the worker thread; then, it sets the stop flag to true. After completing these two steps, it returns immediately without performing the browser close operation. The actual release of browser resources is handled by the worker thread in subsequent checkpoints: after each checkpoint call to the wait method, the worker thread checks the stop flag; if it is true, it closes the browser resources automatically.
[0159] The state management module is configured to have the worker thread stop the test when the stop flag is true.
[0160] The state management module maintains the current state of test tasks, including five states: idle, running, paused, stopped, and completed. When the thread management module starts a worker thread, the state management module sets the state to running; when the pause control module processes a pause request, the state management module sets the state to paused; when the pause control module processes a resume request, the state is restored to running; when the stop control module sets a stop flag, the state management module sets the state to stopped; when a worker thread completes all test steps normally and no stop request is received, the state management module sets the state to completed. The state management module is also responsible for validating state transitions, for example, preventing a direct transition from idle to paused. External front-ends can query the current state at any time via a polling interface to update the user interface.
[0161] The four modules communicate with each other through a shared stop flag and thread event object, but each has a clear responsibility: the thread management module focuses on the thread lifecycle, the pause control module focuses on blocking and waking up the execution flow, the stop control module focuses on the delegation strategy for resource release, and the state management module focuses on the observability of test progress. This modular design allows each part to be optimized and tested independently, reducing the coupling of the system.
[0162] In this embodiment, when an external stop request is received, the stop control module first calls the trigger method of the pause control module to unblock the process, and then sets the stop flag. This sequence utilizes the event object of the pause control module as a signal transmission channel, ensuring that the stop request can be responded to immediately even if the test is in a paused state (the worker thread is blocked on the event object). In the prior art, the stop request and the pause mechanism are independent of each other, causing the stop to fail in the paused state. This device organically integrates the two control mechanisms through inter-module cooperation, achieving complete lifecycle management.
[0163] The thread management module ensures that browser instances are created in worker threads; the stop control module only marks the intent when an external stop request is made without directly closing the browser, which is ultimately closed by the worker thread. These two modules work together to ensure that the creation and closure of browser instances are always completed within the same thread, completely avoiding cross-thread operations and fundamentally compatibility with the limitations of non-thread-safe frameworks such as Playwright.
[0164] By maintaining five clearly defined states and validating the legitimacy of state transitions, the state management module makes the internal behavior of the test engine transparent to the outside world. Operations personnel can view the status of each test task in real time—idle, running, paused, stopped, or completed—facilitating monitoring and fault location. Compared to existing technologies where test scripts can only output logs and lack structured status information, this device significantly improves the manageability of the test service.
[0165] According to another aspect of the embodiments of this application, a test execution control system is provided. This system is deployed on a server as a Web service, providing complete automated test hosting capabilities. The system includes a test execution control device, a Web server, a browser automation framework, and a resource protection module, which work together as follows: The aforementioned test execution control device adopts a modular design, comprising a thread management module, a pause control module, a stop control module, and a state management module. This device serves as the core control hub of the system, responsible for starting and monitoring worker threads, blocking and waking thread event objects, delegating stop request processing, and maintaining the test state. The device operates in a global singleton pattern, ensuring that only one control instance exists in the entire system, thus avoiding state conflicts between multiple test tasks.
[0166] The web server is configured to receive stop, pause, and resume requests via a web interface and provides an HTTP polling interface for external access to execution progress. As the system's external interaction entry point, the web server runs as a persistent process, listening on a specified HTTP port. The web server provides a RESTful API, including at least: a start test interface, a pause interface, a resume interface, a stop interface, and a progress query interface. When a user initiates a control request through the browser frontend, the web server receives the HTTP request and calls the corresponding control method in the test execution control device. For the progress query interface, the web server uses an HTTP polling mechanism: the frontend sends a GET request to this interface at fixed time intervals (e.g., 500 milliseconds), and the web server reads the currently recorded step information (including step number, step description, etc.) from the test execution control device, encapsulates it into a JSON format response, and returns it to the frontend. The polling method is simple to implement, requires no long-lived connections, and is decoupled from the core logic of the test execution control device, without interfering with worker thread blocking or stop flag checks.
[0167] A browser automation framework, configured to execute browser operations in a worker thread, is integrated into the system to handle these operations. When a worker thread starts a test task, it calls the framework's API to launch a browser instance in a persistent context. This browser instance is bound to the worker thread, and all browser operations (such as page navigation, element clicks, and form filling) are initiated by the worker thread through the framework's API. The browser automation framework itself has strict thread safety requirements, demanding that the browser instance be closed within the thread in which it was created. The system's test execution control mechanism satisfies this constraint through a delegated shutdown pattern.
[0168] The resource protection module is configured to register operating system signal handling functions and process exit hooks. When a process exits abnormally, it triggers the stop control module to perform resource cleanup. As a fallback cleanup mechanism, the resource protection module is initialized during system startup. This module performs two registration actions: First, it registers operating system signal handling functions to capture interrupt signals (such as SIGINT, usually generated by the user pressing Ctrl+C) and termination signals (such as SIGTERM, usually sent by the system or container orchestration tools) sent to the process. Second, it registers a process exit hook (e.g., via the atexit mechanism). This hook function is automatically called when the process exits normally or due to an uncaught exception. When a system process exits abnormally due to an external signal, the signal handling function is triggered, and the resource protection module immediately calls the stop control module of the test execution control device to perform the same resource cleanup process as a normal stop request: first, triggering the thread event object to release any possible blockages, then setting the stop flag, and forcibly closing the browser instance. If the signal handling function fails to execute completely for some reason (e.g., interrupted by a second signal), the process exit hook will attempt to perform the same cleanup operation again before the process terminates, providing double protection. The resource protection module is also responsible for recording abnormal logs during the cleanup process, which facilitates post-event investigation by operations and maintenance personnel.
[0169] The overall system workflow is as follows: Users access the web server through a browser frontend. After clicking "Start Test," the test execution control device creates a worker thread. This thread starts the browser instance through the browser automation framework and begins executing the test steps. During execution, users can send pause, resume, or stop requests at any time through the frontend. The web server translates these requests into calls to the test execution control device. If the system process exits due to maintenance operations (such as restarting the service) or an unexpected crash, the resource protection module automatically intervenes to ensure that the browser instance is shut down in a timely manner and does not remain as a zombie process.
[0170] This system organically integrates core control devices, a web server, a browser automation framework, and a resource protection module, forming a complete closed loop from user interaction, task scheduling, browser-driven processes to anomaly mitigation. Unlike the scattered command-line tools or libraries in existing technologies, this system can be directly deployed as an independent testing service for remote use by the team.
[0171] When processing a stop request, the web server's processing thread is not the same as the browser instance creation thread. This system utilizes the delegated shutdown mode in the test execution control mechanism, allowing the web server to only mark the stop intention and unblock, while the worker thread automatically closes the browser. This design enables remote stop functionality without violating the browser automation framework's thread safety restrictions.
[0172] The resource protection module is independent of the test execution control unit and is specifically designed to handle process-level anomalies (such as signals and crashes). When a finally block or context manager in the normal operating path fails to execute, this module provides system-level fallback cleanup. Compared to existing technologies that rely solely on application-layer resource cleanup, this system elevates the protection level to operating system signals and process exit hooks, significantly improving system robustness and reducing the frequency of operational intervention.
[0173] This system uses a polling approach to provide progress queries, rather than embedding a push mechanism in the core control logic. The polling operation is completely independent of worker thread blocking and stop flag checks, and does not increase the synchronization burden on the core path. Furthermore, polling is simple to implement, does not require the web server to support asynchronous I / O or long connections, and reduces the difficulty of system deployment and horizontal scaling. This design maintains the simplicity and reliability of the core control logic while ensuring a good user experience.
[0174] The test execution control unit, web server, browser automation framework, and resource protection module interact through interfaces (such as pause, resume, and stop methods exposed by the control unit; callback functions registered by the resource protection module). Each module can be independently unit tested and simulated; for example, the behavior of the resource protection module after receiving a SIGTERM signal can be tested separately without starting a full browser instance.
[0175] This system not only solves the problems of pausing, resuming, and stopping under normal operation, but also covers edge scenarios of abnormal process exits through a resource protection module. Existing technologies often only focus on normal processes, neglecting the issue of resource residue when services are forcibly terminated. This system, through dual protection of signal processing and exit hooks, elevates the reliability of the testing engine from "usable in most cases" to "usable in enterprise-level production environments."
[0176] It should be noted that the term "comprising" and its variations used in the embodiments of this application are open-ended, meaning "including but not limited to". The term "based on" means "at least partially based on". The term "one embodiment" means "at least one embodiment"; the term "another embodiment" means "at least one additional embodiment"; and the term "some embodiments" means "at least some embodiments". The modifications of "one" and "multiple" mentioned in the embodiments of this application are illustrative and not restrictive. Those skilled in the art should understand that, unless explicitly indicated otherwise in the context, they should be understood as "one or more".
[0177] The steps described in the method embodiments provided in this application can be performed in different orders and / or in parallel. Furthermore, the method embodiments may include additional steps and / or omit the steps shown. The scope of protection of this application is not limited in this respect.
[0178] The term "embodiment" in this specification refers to a specific feature, structure, or characteristic described in connection with an embodiment that may be included in at least one embodiment of this application. The appearance of this phrase in various places throughout the specification does not necessarily imply the same embodiment, nor does it imply independence from or alternative to other embodiments. The various embodiments in this specification are described in a related manner, with reference to each other for similar or identical parts. In particular, for apparatus, device, and system embodiments, since they are substantially similar to method embodiments, the description is relatively simple, and relevant details are referred to in the description of the method embodiments.
[0179] The embodiments described above are merely illustrative of several implementation methods of this application, and while the descriptions are relatively specific and detailed, they should not be construed as limiting the scope of patent protection. It should be noted that those skilled in the art can make various modifications and improvements without departing from the concept of this application, and these all fall within the scope of protection of this application. Therefore, the scope of protection of this application should be determined by the appended claims.
Claims
1. A test execution control method, characterized in that, include: A worker thread is started to execute the test task. During the execution process, the worker thread calls the wait method of the thread event object before each test step: if the thread event object is not triggered, it blocks and waits; if it has been triggered, it checks the stop flag. When the stop flag is true, the worker thread stops the test. When a stop request is received, it is determined whether the current caller is the worker thread: if yes, the current caller sets the stop flag and closes the browser resources; if not, the current caller first triggers the thread event object, then sets the stop flag, and the worker thread detects the stop flag and closes the browser resources automatically.
2. The method according to claim 1, characterized in that, The worker thread is a daemon thread that terminates automatically when the main thread exits.
3. The method according to claim 1, characterized in that, The thread event object is initialized to the triggered state; when a pause request is received, the thread event object is cleared to the untriggered state; when a resume request is received, the thread event object is triggered.
4. The method according to claim 1, characterized in that, Also includes: During initialization, the test state is set to idle; after the worker thread is started, the test state is set to running. When a pause request is received, the test status is set to paused; when a resume request is received, the test status is set to running; when the stop flag is true, the test status is set to stopped; when the test is completed normally, the test status is set to completed.
5. The method according to claim 1, characterized in that, Also includes: Register operating system signal handling functions and process exit hooks to perform browser resource cleanup when the process exits abnormally.
6. The method according to claim 1, characterized in that, After the worker thread resumes from the blocked wait, it immediately checks the stop flag. If the flag is true, the worker thread performs the stop test and closes the browser resources automatically.
7. The method according to claim 1, characterized in that, After the worker thread starts, it establishes a browser persistent context. The step of automatically closing browser resources includes closing the browser instance and releasing the browser instance's persistent context.
8. The method according to claim 1, characterized in that, The stop request, pause request, and resume request are received via a web interface; the worker thread updates the current step information after each test step is executed, so that the execution progress can be obtained externally via the web interface.
9. A test execution control device, characterized in that, include: The thread management module is configured to start worker threads to execute test tasks; The pause control module is configured to control the blocking, waiting, and resumption of the worker thread through a thread event object. Before each test step, the worker thread calls the wait method of the thread event object: if the thread event object is not triggered, it blocks and waits; if it is triggered, it checks the stop flag. The stop control module is configured to determine whether the current caller is the worker thread when a stop request is received: if yes, the stop flag is set and the browser resources are closed; if no, the thread event object is triggered first, and then the stop flag is set, so that the worker thread can automatically close the browser resources after detecting the stop flag. The state management module is configured to terminate the test by the worker thread when the stop flag is true.
10. A test execution control system, characterized in that, include: The test execution control device as described in claim 9; The web server is configured to receive stop, pause, and resume requests via a web interface, and provides an HTTP polling interface for external sources to obtain execution progress. A browser automation framework configured to perform browser operations in the worker thread; The resource protection module is configured to register operating system signal processing functions and process exit hooks, and trigger the stop control module to perform resource cleanup when a process exits abnormally.