测试和调试可观察序列

  如果你有一个可观察的序列在一个延长的时间内发布值,实时测试可以是一个伸展。 Reactive Extension库提供TestScheduler类型,以帮助测试这种时间依赖代码,而不需要等待时间通过。 TestScheduler继承VirtualScheduler并允许您在仿真时间创建,发布和订阅序列。例如,您可以压缩出版物,需要5天才能完成到2分钟运行,同时保持正确的比例。您还可以采用实际上在过去发生的序列(例如,前一年的股票行情序列),并计算或订阅该序列,就像实时推出新值一样。
工厂方法Start执行所有计划任务,直到队列为空,或者您可以指定一个时间,以便排队的任务只执行到指定的时间。
  以下示例使用指定的OnNext通知创建热可观察序列。然后它启动测试调度程序,并指定何时订阅和处理热可观察序列。 Start方法返回ITestableObserver的实例,它包含一个记录列表中所有通知的Messages属性。
  在序列完成之后,我们使用ReactiveAssert.AreElementEqual方法来比较Messages属性以及期望值的列表,以查看两者是否相同(具有相同数量的项目,项目相等且顺序相同) 。通过这样做,我们可以确认我们确实收到了我们期望的通知。在我们的例子中,由于我们只开始在150订阅,我们将错过abc值。然而,当我们比较到目前为止在400处的值时,我们注意到,在我们订阅序列之后,我们实际上已经收到了所有公布的值。我们还验证OnCompleted通知在正确的时间在500处触发。此外,订阅信息也由CreateHotObservable方法返回的ITestableObservable类型捕获。
  以同样的方式,您可以使用ReactiveAssert.AreElementsEqual来确认订阅确实发生在预期的时间。

using System;
using System.Reactive;
using System.Reactive.Linq;
using Microsoft.Reactive.Testing;

class Program : ReactiveTest
{
    static void Main(string[] args)
    {
        var scheduler = new TestScheduler();

        var input = scheduler.CreateHotObservable(
            OnNext(100, "abc"),
            OnNext(200, "def"),
            OnNext(250, "ghi"),
            OnNext(300, "pqr"),
            OnNext(450, "xyz"),
            OnCompleted<string>(500)
            );

        var results = scheduler.Start(
            () => input.Buffer(() => input.Throttle(TimeSpan.FromTicks(100), scheduler))
                       .Select(b => string.Join(",", b)),
            created: 50,
            subscribed: 150,
            disposed: 600);

        ReactiveAssert.AreElementsEqual(results.Messages, new Recorded<Notification<string>>[] {
                OnNext(400, "def,ghi,pqr"),
                OnNext(500, "xyz"),
                OnCompleted<string>(500)
            });

        ReactiveAssert.AreElementsEqual(input.Subscriptions, new Subscription[] {
                Subscribe(150, 500),
                Subscribe(150, 400),
                Subscribe(400, 500)
            });
    }
}

调试Rx应用程序

  您可以使用Do操作符调试Rx应用程序。 Do操作符允许您指定为可观察序列的每个项目采取的各种动作(例如,打印或记录项目等)。这在您链接许多运算符并且想要知道在每个级别生成什么值时尤其有用。
  在下面的例子中,我们将重用Buffer示例,每秒生成一个整数,同时将它们放入可以容纳5个项目的缓冲区中。在我们使用LINQ运算符的查询可观察序列的原始示例中,当缓冲区已满(并且在其被清空之前)时,我们仅订阅最终的Observable(IList <>)序列。然而,在这个例子中,我们将使用Do操作符,当它们被原始序列(每秒一个整数)推出时,打印出值。当缓冲区已满时,我们使用Do操作符打印状态,然后将所有这些作为观察者订阅的最后序列。

var seq1 = Observable.Interval(TimeSpan.FromSeconds(1))
           .Do(x => Console.WriteLine(x.ToString()))
           .Buffer(5)
           .Do(x => Console.WriteLine("buffer is full"))
           .Subscribe(x => Console.WriteLine("Sum of the buffer is " + x.Sum()));
Console.ReadKey();

  从此示例中可以看出,订阅位于一系列链接的可观察序列的收件人端。首先,我们使用Interval运算符创建一个可观察的整数序列,以秒为单位。然后,我们使用Buffer操作符将5个项目放入一个缓冲区中,并且只有当缓冲区已满时才将它们作为另一个序列发送出去。最后,这被交给Subscribe运算符。数据沿着所有这些中间序列传播,直到它们被推送到观察者。以相同的方式,订阅以与源序列相反的方向传播。通过在这样的传播过程中插入Do操作符,您可以对这种数据流进行“间谍”,就像在.NET中使用Console.WriteLine或在C中使用printf()执行调试一样。
  您还可以使用Timestamp运算符来验证项目按可观察序列推出的时间。这可以帮助您排除基于时间的操作,以确保准确性。回想一下创建和订阅简单可观察序列主题中的以下示例,其中我们将Timestamp运算符链接到查询,以便源序列推出的每个值将在发布时附加。通过这样做,当我们订阅这个源序列时,我们可以接收它的值和时间戳。

Console.WriteLine(“Current Time: “ + DateTime.Now);

var source = Observable.Timer(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(1))
                       .Timestamp();
using (source.Subscribe(x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp)))
      {
           Console.WriteLine("Press any key to unsubscribe");
           Console.ReadKey();
      }
Console.WriteLine("Press any key to exit");
Console.ReadKey();

输出如下:
Current Time: 5/31/2011 5:35:08 PM
Press any key to unsubscribe
0: 5/31/2011 5:35:13 PM -07:00
1: 5/31/2011 5:35:14 PM -07:00
2: 5/31/2011 5:35:15 PM -07:00

通过使用Timestamp运算符,我们验证了第一个项目确实在序列之后5秒被推出,每个项目在1秒后发布。
此外,您还可以在lambda表达式中设置断点以协助调试。 通常,您只能为整个查询设置断点,而不必选择特定值来查看它。 要解决此限制,您可以在查询中间插入Select运算符,并在其中设置断点,并在Select语句中,使用自己的行上的return语句将相同的值投影到其源。 然后,您可以在返回语句行设置断点,并在查找值时检查值

var seq = Observable.Interval(TimeSpan.FromSeconds(1))
          .Do(x => Console.WriteLine(x.ToString()))
          .Buffer(5)
          .Select(y => { 
                  return y; }) // set a breakpoint at this line
          .Do(x => Console.WriteLine("buffer is full"))
          .Subscribe(x => Console.WriteLine("Sum of the buffer is " + x.Sum()));
Console.ReadKey();

  在此示例中,断点设置在返回y线。 当调试到程序中时,y变量显示在Locals窗口中,您可以检查其总数(5)。 如果您展开y,您还可以检查列表中的每个项目,包括其值和类型。
  或者,您可以将lambda表达式转换为语句lambda表达式,格式代码,以便语句在其自己的行上,然后设置断点。
  完成调试后,可以删除任何Do和Select调用。

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值