Skip to main content

wae_testing/
environment.rs

1//! 测试环境管理模块
2//!
3//! 提供完整的测试生命周期管理、多服务集成测试支持和容器化测试环境。
4
5use parking_lot::RwLock;
6use std::{
7    collections::HashMap,
8    fmt,
9    future::Future,
10    sync::Arc,
11    time::{Duration, Instant},
12};
13use wae_types::{WaeError, WaeErrorKind, WaeResult as TestingResult};
14
15/// 测试环境配置
16#[derive(Debug, Clone)]
17pub struct TestEnvConfig {
18    /// 环境名称
19    pub name: String,
20    /// 是否启用日志
21    pub enable_logging: bool,
22    /// 是否启用追踪
23    pub enable_tracing: bool,
24    /// 超时时间
25    pub default_timeout: Duration,
26    /// 自定义配置
27    pub custom: HashMap<String, String>,
28}
29
30impl Default for TestEnvConfig {
31    fn default() -> Self {
32        Self {
33            name: "test".to_string(),
34            enable_logging: true,
35            enable_tracing: false,
36            default_timeout: Duration::from_secs(30),
37            custom: HashMap::new(),
38        }
39    }
40}
41
42impl TestEnvConfig {
43    /// 创建新的测试环境配置
44    pub fn new() -> Self {
45        Self::default()
46    }
47
48    /// 设置环境名称
49    pub fn name(mut self, name: impl Into<String>) -> Self {
50        self.name = name.into();
51        self
52    }
53
54    /// 启用日志
55    pub fn with_logging(mut self, enable: bool) -> Self {
56        self.enable_logging = enable;
57        self
58    }
59
60    /// 启用追踪
61    pub fn with_tracing(mut self, enable: bool) -> Self {
62        self.enable_tracing = enable;
63        self
64    }
65
66    /// 设置超时时间
67    pub fn timeout(mut self, timeout: Duration) -> Self {
68        self.default_timeout = timeout;
69        self
70    }
71
72    /// 添加自定义配置
73    pub fn custom(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
74        self.custom.insert(key.into(), value.into());
75        self
76    }
77}
78
79/// 测试环境状态
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub enum TestEnvState {
82    /// 未初始化
83    Uninitialized,
84    /// 正在初始化
85    Initializing,
86    /// 已初始化
87    Initialized,
88    /// 正在销毁
89    Destroying,
90    /// 已销毁
91    Destroyed,
92}
93
94/// 测试生命周期钩子 trait
95///
96/// 定义测试环境在各个阶段执行的钩子函数,用于自定义测试环境的初始化和清理逻辑。
97pub trait TestLifecycleHook: Send + Sync {
98    /// 在测试环境初始化之前执行
99    ///
100    /// # Errors
101    ///
102    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
103    fn before_setup(&self, _env: &TestEnv) -> TestingResult<()> {
104        Ok(())
105    }
106
107    /// 在测试环境初始化之后执行
108    ///
109    /// # Errors
110    ///
111    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
112    fn after_setup(&self, _env: &TestEnv) -> TestingResult<()> {
113        Ok(())
114    }
115
116    /// 在测试环境清理之前执行
117    ///
118    /// # Errors
119    ///
120    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
121    fn before_teardown(&self, _env: &TestEnv) -> TestingResult<()> {
122        Ok(())
123    }
124
125    /// 在测试环境清理之后执行
126    ///
127    /// # Errors
128    ///
129    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
130    fn after_teardown(&self, _env: &TestEnv) -> TestingResult<()> {
131        Ok(())
132    }
133}
134
135impl<F> TestLifecycleHook for F
136where
137    F: Fn(&TestEnv) -> TestingResult<()> + Send + Sync,
138{
139    fn after_setup(&self, env: &TestEnv) -> TestingResult<()> {
140        self(env)
141    }
142}
143
144/// 异步测试生命周期钩子 trait
145///
146/// 定义测试环境在各个阶段执行的异步钩子函数,支持异步操作的初始化和清理。
147#[async_trait::async_trait]
148pub trait AsyncTestLifecycleHook: Send + Sync {
149    /// 在测试环境初始化之前异步执行
150    ///
151    /// # Errors
152    ///
153    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
154    async fn before_setup_async(&self, _env: &TestEnv) -> TestingResult<()> {
155        Ok(())
156    }
157
158    /// 在测试环境初始化之后异步执行
159    ///
160    /// # Errors
161    ///
162    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
163    async fn after_setup_async(&self, _env: &TestEnv) -> TestingResult<()> {
164        Ok(())
165    }
166
167    /// 在测试环境清理之前异步执行
168    ///
169    /// # Errors
170    ///
171    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
172    async fn before_teardown_async(&self, _env: &TestEnv) -> TestingResult<()> {
173        Ok(())
174    }
175
176    /// 在测试环境清理之后异步执行
177    ///
178    /// # Errors
179    ///
180    /// 如果钩子执行失败,将返回 [`WaeError`] 错误。
181    async fn after_teardown_async(&self, _env: &TestEnv) -> TestingResult<()> {
182        Ok(())
183    }
184}
185
186/// 测试服务配置
187///
188/// 定义测试环境中需要启动的服务配置,支持多服务集成测试。
189#[derive(Debug, Clone)]
190pub struct TestServiceConfig {
191    /// 服务名称
192    pub name: String,
193    /// 服务是否启用
194    pub enabled: bool,
195    /// 服务启动超时时间
196    pub startup_timeout: Duration,
197    /// 服务特定配置
198    pub config: HashMap<String, String>,
199}
200
201impl TestServiceConfig {
202    /// 创建新的测试服务配置
203    pub fn new(name: impl Into<String>) -> Self {
204        Self { name: name.into(), enabled: true, startup_timeout: Duration::from_secs(30), config: HashMap::new() }
205    }
206
207    /// 设置服务启用状态
208    pub fn enabled(mut self, enabled: bool) -> Self {
209        self.enabled = enabled;
210        self
211    }
212
213    /// 设置服务启动超时时间
214    pub fn startup_timeout(mut self, timeout: Duration) -> Self {
215        self.startup_timeout = timeout;
216        self
217    }
218
219    /// 添加服务配置项
220    pub fn config(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
221        self.config.insert(key.into(), value.into());
222        self
223    }
224}
225
226/// 测试环境管理器
227///
228/// 提供完整的测试生命周期管理,支持同步和异步钩子函数,多服务集成测试,以及容器化测试环境。
229pub struct TestEnv {
230    /// 配置
231    config: TestEnvConfig,
232    /// 状态
233    state: Arc<RwLock<TestEnvState>>,
234    /// 创建时间
235    created_at: Instant,
236    /// 初始化完成时间
237    initialized_at: Arc<RwLock<Option<Instant>>>,
238    /// 同步生命周期钩子
239    lifecycle_hooks: Arc<RwLock<Vec<Box<dyn TestLifecycleHook>>>>,
240    /// 异步生命周期钩子
241    async_lifecycle_hooks: Arc<RwLock<Vec<Box<dyn AsyncTestLifecycleHook>>>>,
242    /// 清理函数列表
243    #[allow(clippy::type_complexity)]
244    cleanup_handlers: Arc<RwLock<Vec<Box<dyn Fn() + Send + Sync>>>>,
245    /// 异步清理函数列表
246    #[allow(clippy::type_complexity)]
247    async_cleanup_handlers: Arc<RwLock<Vec<Box<dyn Fn() -> std::pin::Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>>>>,
248    /// 存储的数据
249    storage: Arc<RwLock<HashMap<String, Box<dyn std::any::Any + Send + Sync>>>>,
250    /// 测试服务配置
251    services: Arc<RwLock<HashMap<String, TestServiceConfig>>>,
252}
253
254impl fmt::Debug for TestEnv {
255    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256        f.debug_struct("TestEnv")
257            .field("config", &self.config)
258            .field("state", &self.state)
259            .field("created_at", &self.created_at)
260            .field("initialized_at", &self.initialized_at)
261            .field("services", &self.services)
262            .finish()
263    }
264}
265
266impl TestEnv {
267    /// 创建新的测试环境
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// use wae_testing::{TestEnv, TestEnvConfig};
273    ///
274    /// let config = TestEnvConfig::default();
275    /// let env = TestEnv::new(config);
276    /// ```
277    pub fn new(config: TestEnvConfig) -> Self {
278        Self {
279            config,
280            state: Arc::new(RwLock::new(TestEnvState::Uninitialized)),
281            created_at: Instant::now(),
282            initialized_at: Arc::new(RwLock::new(None)),
283            lifecycle_hooks: Arc::new(RwLock::new(Vec::new())),
284            async_lifecycle_hooks: Arc::new(RwLock::new(Vec::new())),
285            cleanup_handlers: Arc::new(RwLock::new(Vec::new())),
286            async_cleanup_handlers: Arc::new(RwLock::new(Vec::new())),
287            storage: Arc::new(RwLock::new(HashMap::new())),
288            services: Arc::new(RwLock::new(HashMap::new())),
289        }
290    }
291
292    /// 创建默认测试环境
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// use wae_testing::TestEnv;
298    ///
299    /// let env = TestEnv::default_env();
300    /// ```
301    pub fn default_env() -> Self {
302        Self::new(TestEnvConfig::default())
303    }
304
305    /// 初始化测试环境
306    ///
307    /// 按顺序执行所有 `before_setup` 钩子、初始化环境、然后执行所有 `after_setup` 钩子。
308    ///
309    /// # Errors
310    ///
311    /// 如果环境已初始化或任何钩子执行失败,将返回 [`WaeError`] 错误。
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// use wae_testing::TestEnv;
317    ///
318    /// let env = TestEnv::default_env();
319    /// env.setup().unwrap();
320    /// ```
321    pub fn setup(&self) -> TestingResult<()> {
322        {
323            let mut state = self.state.write();
324            if *state != TestEnvState::Uninitialized {
325                return Err(WaeError::new(WaeErrorKind::EnvironmentError {
326                    reason: "Environment already initialized".to_string(),
327                }));
328            }
329            *state = TestEnvState::Initializing;
330        }
331
332        let result = (|| {
333            for hook in self.lifecycle_hooks.read().iter() {
334                hook.before_setup(self)?;
335            }
336
337            for hook in self.lifecycle_hooks.read().iter() {
338                hook.after_setup(self)?;
339            }
340
341            Ok(())
342        })();
343
344        let mut state = self.state.write();
345        match result {
346            Ok(_) => {
347                *state = TestEnvState::Initialized;
348                *self.initialized_at.write() = Some(Instant::now());
349                Ok(())
350            }
351            Err(e) => {
352                *state = TestEnvState::Uninitialized;
353                Err(e)
354            }
355        }
356    }
357
358    /// 异步初始化测试环境
359    ///
360    /// 异步执行所有生命周期钩子函数,适合需要异步初始化的场景。
361    ///
362    /// # Errors
363    ///
364    /// 如果环境已初始化或任何钩子执行失败,将返回 [`WaeError`] 错误。
365    pub async fn setup_async(&self) -> TestingResult<()> {
366        {
367            let mut state = self.state.write();
368            if *state != TestEnvState::Uninitialized {
369                return Err(WaeError::new(WaeErrorKind::EnvironmentError {
370                    reason: "Environment already initialized".to_string(),
371                }));
372            }
373            *state = TestEnvState::Initializing;
374        }
375
376        let result = (async {
377            for hook in self.lifecycle_hooks.read().iter() {
378                hook.before_setup(self)?;
379            }
380
381            for hook in self.async_lifecycle_hooks.read().iter() {
382                hook.before_setup_async(self).await?;
383            }
384
385            for hook in self.async_lifecycle_hooks.read().iter() {
386                hook.after_setup_async(self).await?;
387            }
388
389            for hook in self.lifecycle_hooks.read().iter() {
390                hook.after_setup(self)?;
391            }
392
393            Ok(())
394        })
395        .await;
396
397        let mut state = self.state.write();
398        match result {
399            Ok(_) => {
400                *state = TestEnvState::Initialized;
401                *self.initialized_at.write() = Some(Instant::now());
402                Ok(())
403            }
404            Err(e) => {
405                *state = TestEnvState::Uninitialized;
406                Err(e)
407            }
408        }
409    }
410
411    /// 清理测试环境
412    ///
413    /// 按顺序执行所有 `before_teardown` 钩子、清理资源、然后执行所有 `after_teardown` 钩子。
414    ///
415    /// # Errors
416    ///
417    /// 如果环境未初始化或任何钩子执行失败,将返回 [`WaeError`] 错误。
418    ///
419    /// # Examples
420    ///
421    /// ```
422    /// use wae_testing::TestEnv;
423    ///
424    /// let env = TestEnv::default_env();
425    /// env.setup().unwrap();
426    /// env.teardown().unwrap();
427    /// ```
428    pub fn teardown(&self) -> TestingResult<()> {
429        {
430            let mut state = self.state.write();
431            if *state != TestEnvState::Initialized {
432                return Err(WaeError::new(WaeErrorKind::EnvironmentError {
433                    reason: "Environment not initialized".to_string(),
434                }));
435            }
436            *state = TestEnvState::Destroying;
437        }
438
439        let result = (|| {
440            for hook in self.lifecycle_hooks.read().iter() {
441                hook.before_teardown(self)?;
442            }
443
444            let handlers = self.cleanup_handlers.write();
445            for handler in handlers.iter().rev() {
446                handler();
447            }
448
449            self.storage.write().clear();
450
451            for hook in self.lifecycle_hooks.read().iter() {
452                hook.after_teardown(self)?;
453            }
454
455            Ok(())
456        })();
457
458        let mut state = self.state.write();
459        *state = TestEnvState::Destroyed;
460        result
461    }
462
463    /// 异步清理测试环境
464    ///
465    /// 异步执行所有清理操作,适合需要异步清理的场景。
466    ///
467    /// # Errors
468    ///
469    /// 如果环境未初始化或任何钩子执行失败,将返回 [`WaeError`] 错误。
470    pub async fn teardown_async(&self) -> TestingResult<()> {
471        {
472            let mut state = self.state.write();
473            if *state != TestEnvState::Initialized {
474                return Err(WaeError::new(WaeErrorKind::EnvironmentError {
475                    reason: "Environment not initialized".to_string(),
476                }));
477            }
478            *state = TestEnvState::Destroying;
479        }
480
481        let result = (async {
482            for hook in self.lifecycle_hooks.read().iter() {
483                hook.before_teardown(self)?;
484            }
485
486            for hook in self.async_lifecycle_hooks.read().iter() {
487                hook.before_teardown_async(self).await?;
488            }
489
490            {
491                let handlers = self.async_cleanup_handlers.write();
492                for handler in handlers.iter().rev() {
493                    handler().await;
494                }
495            }
496
497            {
498                let handlers = self.cleanup_handlers.write();
499                for handler in handlers.iter().rev() {
500                    handler();
501                }
502            }
503
504            self.storage.write().clear();
505
506            for hook in self.async_lifecycle_hooks.read().iter() {
507                hook.after_teardown_async(self).await?;
508            }
509
510            for hook in self.lifecycle_hooks.read().iter() {
511                hook.after_teardown(self)?;
512            }
513
514            Ok(())
515        })
516        .await;
517
518        let mut state = self.state.write();
519        *state = TestEnvState::Destroyed;
520        result
521    }
522
523    /// 获取环境状态
524    ///
525    /// # Examples
526    ///
527    /// ```
528    /// use wae_testing::{TestEnv, TestEnvState};
529    ///
530    /// let env = TestEnv::default_env();
531    /// assert_eq!(env.state(), TestEnvState::Uninitialized);
532    /// ```
533    pub fn state(&self) -> TestEnvState {
534        self.state.read().clone()
535    }
536
537    /// 获取环境运行时间
538    ///
539    /// 返回从环境创建到现在经过的时间。
540    pub fn elapsed(&self) -> Duration {
541        self.created_at.elapsed()
542    }
543
544    /// 获取环境初始化后运行的时间
545    ///
546    /// 如果环境尚未初始化,返回 [`None`]。
547    pub fn initialized_elapsed(&self) -> Option<Duration> {
548        self.initialized_at.read().map(|t| t.elapsed())
549    }
550
551    /// 注册同步生命周期钩子
552    ///
553    /// 添加一个同步钩子函数,在测试环境的各个生命周期阶段执行。
554    ///
555    /// # Examples
556    ///
557    /// ```
558    /// use wae_testing::TestEnv;
559    ///
560    /// struct MyHook;
561    ///
562    /// impl wae_testing::TestLifecycleHook for MyHook {
563    ///     fn after_setup(&self, _env: &TestEnv) -> wae_testing::TestingResult<()> {
564    ///         println!("Environment setup complete!");
565    ///         Ok(())
566    ///     }
567    /// }
568    ///
569    /// let env = TestEnv::default_env();
570    /// env.add_lifecycle_hook(MyHook);
571    /// ```
572    pub fn add_lifecycle_hook<H>(&self, hook: H)
573    where
574        H: TestLifecycleHook + 'static,
575    {
576        self.lifecycle_hooks.write().push(Box::new(hook));
577    }
578
579    /// 注册异步生命周期钩子
580    ///
581    /// 添加一个异步钩子函数,在测试环境的各个生命周期阶段异步执行。
582    pub fn add_async_lifecycle_hook<H>(&self, hook: H)
583    where
584        H: AsyncTestLifecycleHook + 'static,
585    {
586        self.async_lifecycle_hooks.write().push(Box::new(hook));
587    }
588
589    /// 注册清理函数
590    ///
591    /// 添加一个同步清理函数,在测试环境清理时执行。清理函数按注册的逆序执行。
592    ///
593    /// # Examples
594    ///
595    /// ```
596    /// use wae_testing::TestEnv;
597    ///
598    /// let env = TestEnv::default_env();
599    /// env.on_cleanup(|| println!("Cleaning up!"));
600    /// ```
601    pub fn on_cleanup<F>(&self, handler: F)
602    where
603        F: Fn() + Send + Sync + 'static,
604    {
605        self.cleanup_handlers.write().push(Box::new(handler));
606    }
607
608    /// 注册异步清理函数
609    ///
610    /// 添加一个异步清理函数,在测试环境清理时异步执行。
611    pub fn on_cleanup_async<F, Fut>(&self, handler: F)
612    where
613        F: Fn() -> Fut + Send + Sync + 'static,
614        Fut: Future<Output = ()> + Send + 'static,
615    {
616        self.async_cleanup_handlers.write().push(Box::new(move || Box::pin(handler())));
617    }
618
619    /// 存储数据
620    ///
621    /// 在测试环境中存储任意类型的数据。
622    ///
623    /// # Examples
624    ///
625    /// ```
626    /// use wae_testing::TestEnv;
627    ///
628    /// let env = TestEnv::default_env();
629    /// env.set("test_key", "test_value");
630    /// ```
631    pub fn set<T: 'static + Send + Sync>(&self, key: &str, value: T) {
632        self.storage.write().insert(key.to_string(), Box::new(value));
633    }
634
635    /// 获取数据
636    ///
637    /// 从测试环境中获取之前存储的数据。
638    ///
639    /// # Examples
640    ///
641    /// ```
642    /// use wae_testing::TestEnv;
643    ///
644    /// let env = TestEnv::default_env();
645    /// env.set("test_key", "test_value".to_string());
646    /// let value: Option<String> = env.get("test_key");
647    /// assert_eq!(value, Some("test_value".to_string()));
648    /// ```
649    pub fn get<T: 'static + Clone>(&self, key: &str) -> Option<T> {
650        let storage = self.storage.read();
651        storage.get(key).and_then(|v| v.downcast_ref::<T>().cloned())
652    }
653
654    /// 移除数据
655    ///
656    /// 从测试环境中移除并返回之前存储的数据。
657    pub fn remove<T: 'static>(&self, key: &str) -> Option<T> {
658        let mut storage = self.storage.write();
659        storage.remove(key).and_then(|v| v.downcast::<T>().ok()).map(|v| *v)
660    }
661
662    /// 检查是否存在指定键的数据
663    pub fn has(&self, key: &str) -> bool {
664        self.storage.read().contains_key(key)
665    }
666
667    /// 获取配置
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// use wae_testing::TestEnv;
673    ///
674    /// let env = TestEnv::default_env();
675    /// let config = env.config();
676    /// assert_eq!(config.name, "test");
677    /// ```
678    pub fn config(&self) -> &TestEnvConfig {
679        &self.config
680    }
681
682    /// 添加测试服务配置
683    ///
684    /// 向测试环境中添加一个服务配置,用于多服务集成测试。
685    pub fn add_service(&self, service_config: TestServiceConfig) {
686        self.services.write().insert(service_config.name.clone(), service_config);
687    }
688
689    /// 获取测试服务配置
690    ///
691    /// 根据服务名称获取服务配置。
692    pub fn get_service(&self, name: &str) -> Option<TestServiceConfig> {
693        self.services.read().get(name).cloned()
694    }
695
696    /// 获取所有启用的服务
697    ///
698    /// 返回所有已启用的服务配置列表。
699    pub fn enabled_services(&self) -> Vec<TestServiceConfig> {
700        self.services.read().values().filter(|s| s.enabled).cloned().collect()
701    }
702
703    /// 使用 fixture 运行测试
704    ///
705    /// 自动管理测试环境的初始化和清理,执行测试函数。
706    ///
707    /// # Errors
708    ///
709    /// 如果环境初始化、测试执行或清理失败,将返回 [`WaeError`] 错误。
710    pub async fn with_fixture<F, R>(&self, fixture: F) -> TestingResult<R>
711    where
712        F: FnOnce() -> TestingResult<R>,
713    {
714        self.setup()?;
715
716        let result = fixture();
717
718        self.teardown()?;
719
720        result
721    }
722
723    /// 运行异步测试
724    ///
725    /// 自动管理测试环境的初始化和清理,执行异步测试函数。
726    ///
727    /// # Errors
728    ///
729    /// 如果环境初始化、测试执行或清理失败,将返回 [`WaeError`] 错误。
730    ///
731    /// # Examples
732    ///
733    /// ```ignore
734    /// use wae_testing::TestEnv;
735    ///
736    /// let env = TestEnv::default_env();
737    /// env.run_test(|| async { Ok(()) }).await.unwrap();
738    /// ```
739    pub async fn run_test<F, Fut>(&self, test: F) -> TestingResult<()>
740    where
741        F: FnOnce() -> Fut,
742        Fut: Future<Output = TestingResult<()>>,
743    {
744        self.setup()?;
745
746        let result = test().await;
747
748        self.teardown()?;
749
750        result
751    }
752
753    /// 运行带异步生命周期的测试
754    ///
755    /// 使用异步初始化和清理运行测试,适合需要异步操作的测试场景。
756    ///
757    /// # Errors
758    ///
759    /// 如果环境初始化、测试执行或清理失败,将返回 [`WaeError`] 错误。
760    pub async fn run_test_async<F, Fut>(&self, test: F) -> TestingResult<()>
761    where
762        F: FnOnce() -> Fut,
763        Fut: Future<Output = TestingResult<()>>,
764    {
765        self.setup_async().await?;
766
767        let result = test().await;
768
769        self.teardown_async().await?;
770
771        result
772    }
773}
774
775impl Drop for TestEnv {
776    fn drop(&mut self) {
777        let state = self.state.read().clone();
778        if state == TestEnvState::Initialized {
779            let _ = self.teardown();
780        }
781    }
782}
783
784/// 测试环境构建器
785///
786/// 提供流式 API 构建测试环境,支持配置、生命周期钩子和多服务设置。
787pub struct TestEnvBuilder {
788    config: TestEnvConfig,
789    lifecycle_hooks: Vec<Box<dyn TestLifecycleHook>>,
790    async_lifecycle_hooks: Vec<Box<dyn AsyncTestLifecycleHook>>,
791    services: Vec<TestServiceConfig>,
792}
793
794impl TestEnvBuilder {
795    /// 创建新的构建器
796    ///
797    /// # Examples
798    ///
799    /// ```
800    /// use wae_testing::TestEnvBuilder;
801    ///
802    /// let builder = TestEnvBuilder::new();
803    /// ```
804    pub fn new() -> Self {
805        Self {
806            config: TestEnvConfig::default(),
807            lifecycle_hooks: Vec::new(),
808            async_lifecycle_hooks: Vec::new(),
809            services: Vec::new(),
810        }
811    }
812
813    /// 设置环境名称
814    ///
815    /// # Examples
816    ///
817    /// ```
818    /// use wae_testing::TestEnvBuilder;
819    ///
820    /// let env = TestEnvBuilder::new().name("my_test_env").build();
821    /// ```
822    pub fn name(mut self, name: impl Into<String>) -> Self {
823        self.config.name = name.into();
824        self
825    }
826
827    /// 启用日志
828    ///
829    /// # Examples
830    ///
831    /// ```
832    /// use wae_testing::TestEnvBuilder;
833    ///
834    /// let env = TestEnvBuilder::new().with_logging(false).build();
835    /// ```
836    pub fn with_logging(mut self, enable: bool) -> Self {
837        self.config.enable_logging = enable;
838        self
839    }
840
841    /// 启用追踪
842    ///
843    /// # Examples
844    ///
845    /// ```
846    /// use wae_testing::TestEnvBuilder;
847    ///
848    /// let env = TestEnvBuilder::new().with_tracing(true).build();
849    /// ```
850    pub fn with_tracing(mut self, enable: bool) -> Self {
851        self.config.enable_tracing = enable;
852        self
853    }
854
855    /// 设置超时时间
856    ///
857    /// # Examples
858    ///
859    /// ```
860    /// use std::time::Duration;
861    /// use wae_testing::TestEnvBuilder;
862    ///
863    /// let env = TestEnvBuilder::new().timeout(Duration::from_secs(60)).build();
864    /// ```
865    pub fn timeout(mut self, timeout: Duration) -> Self {
866        self.config.default_timeout = timeout;
867        self
868    }
869
870    /// 添加自定义配置
871    ///
872    /// # Examples
873    ///
874    /// ```
875    /// use wae_testing::TestEnvBuilder;
876    ///
877    /// let env = TestEnvBuilder::new().custom("key", "value").build();
878    /// ```
879    pub fn custom(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
880        self.config.custom.insert(key.into(), value.into());
881        self
882    }
883
884    /// 添加同步生命周期钩子
885    ///
886    /// # Examples
887    ///
888    /// ```
889    /// use wae_testing::{TestEnv, TestEnvBuilder, TestLifecycleHook};
890    ///
891    /// struct MyHook;
892    ///
893    /// impl TestLifecycleHook for MyHook {}
894    ///
895    /// let env = TestEnvBuilder::new().with_lifecycle_hook(MyHook).build();
896    /// ```
897    pub fn with_lifecycle_hook<H>(mut self, hook: H) -> Self
898    where
899        H: TestLifecycleHook + 'static,
900    {
901        self.lifecycle_hooks.push(Box::new(hook));
902        self
903    }
904
905    /// 添加异步生命周期钩子
906    pub fn with_async_lifecycle_hook<H>(mut self, hook: H) -> Self
907    where
908        H: AsyncTestLifecycleHook + 'static,
909    {
910        self.async_lifecycle_hooks.push(Box::new(hook));
911        self
912    }
913
914    /// 添加测试服务配置
915    ///
916    /// 向构建器中添加一个服务配置,构建时会自动注册到测试环境。
917    ///
918    /// # Examples
919    ///
920    /// ```
921    /// use wae_testing::{TestEnvBuilder, TestServiceConfig};
922    ///
923    /// let env = TestEnvBuilder::new().with_service(TestServiceConfig::new("database")).build();
924    /// ```
925    pub fn with_service(mut self, service: TestServiceConfig) -> Self {
926        self.services.push(service);
927        self
928    }
929
930    /// 批量添加测试服务配置
931    ///
932    /// 向构建器中添加多个服务配置。
933    pub fn with_services<I>(mut self, services: I) -> Self
934    where
935        I: IntoIterator<Item = TestServiceConfig>,
936    {
937        self.services.extend(services);
938        self
939    }
940
941    /// 构建测试环境
942    ///
943    /// 使用当前配置构建并返回测试环境实例。
944    ///
945    /// # Examples
946    ///
947    /// ```
948    /// use wae_testing::TestEnvBuilder;
949    ///
950    /// let env = TestEnvBuilder::new().build();
951    /// ```
952    pub fn build(self) -> TestEnv {
953        let env = TestEnv::new(self.config);
954
955        for hook in self.lifecycle_hooks {
956            env.lifecycle_hooks.write().push(hook);
957        }
958
959        for hook in self.async_lifecycle_hooks {
960            env.async_lifecycle_hooks.write().push(hook);
961        }
962
963        for service in self.services {
964            env.add_service(service);
965        }
966
967        env
968    }
969}
970
971impl Default for TestEnvBuilder {
972    fn default() -> Self {
973        Self::new()
974    }
975}
976
977/// 创建测试环境
978///
979/// 便捷函数,创建一个默认配置的测试环境。
980///
981/// # Examples
982///
983/// ```
984/// use wae_testing::create_test_env;
985///
986/// let env = create_test_env();
987/// ```
988pub fn create_test_env() -> TestEnv {
989    TestEnv::default_env()
990}
991
992/// 使用配置创建测试环境
993///
994/// 便捷函数,使用指定配置创建测试环境。
995///
996/// # Examples
997///
998/// ```
999/// use wae_testing::{TestEnvConfig, create_test_env_with_config};
1000///
1001/// let config = TestEnvConfig::default();
1002/// let env = create_test_env_with_config(config);
1003/// ```
1004pub fn create_test_env_with_config(config: TestEnvConfig) -> TestEnv {
1005    TestEnv::new(config)
1006}