Kedro 6个月

我们在两种模式下构建人工智能软件:实验和产品化。在实验过程中,我们试图看到如果现代技术将解决我们的问题。如果成功了,我们就会转向产品化,大规模地建立可靠的数据管道。

当涉及到数据工程时,这就呈现出一种周期性依赖。在实验期间,我们需要可靠和可维护的数据工程管道,但不知道什么在我们完成实验之前那条管道应该没问题。在过去,我和我认识的许多数据科学家都使用过an特别的bash脚本和Jupyter notebook的组合来整理实验数据。虽然这可能是获得实验结果和模型构建的最快方式,但这确实是一笔必须在未来偿还的技术债务。

这个问题

具体来说,实验数据管道的临时方法会导致以下问题:

  • 再现性:特别的实验结构会让你面临其他人无法重现的结果的风险,如果你需要更新你的方法,这可能会导致产品停机。一些简单的错误,如两次执行一个笔记本单元格或忘记给随机数生成器播种,通常都可以被捕捉到。但是可能会出现其他更隐蔽的问题,比如依赖版本之间的行为变化。
  • 可读性:如果你曾经遇到过别人的实验代码,你就会知道很难找到从哪里开始。甚至有文档记录的项目也可能只是说“运行x脚本,y笔记本等”,通常不清楚数据来自哪里,也不清楚你是否在正确的轨道上。类似地,数据科学项目的代码审查通常很难阅读:它要求读者区分用于数据操作的笔记本代码和用于可视化的代码。
  • 可维护性:在数据科学项目中,做一些探索性分析或生成早期结果,然后修改处理或收集数据的方式是很常见的。当所有这些步骤都是非结构化的笔记本或脚本集合时,这就变得困难和乏味了。换句话说,管道很难维护:更新或更改它需要您跟踪整个事情。
  • Shareability:对于团队来说,同时处理笔记本和bash脚本的特别集合也很困难。每个成员都必须确保他们的笔记本是最新的(笔记本的版本控制不太理想),并且他们有任何中间数据的正确副本。

进入Kedro

上面的许多问题对于软件工程学科来说并不新鲜,并且在该领域已经得到了很大程度的解决。这就是Kedro出现的原因。Kedro是一个用于构建数据工程管道的框架,其结构迫使您遵循良好的软件工程实践。通过在项目的实验阶段使用Kedro,我们建立了可维护和可重复的数据管道,产生一致的实验结果。

具体来说,Kedro让您将数据工程代码组织成一个或多个管道.每个管道由若干节点:以一些数据集和参数作为输入并产生新的数据集、模型或工件的功能单元。

这个简单但严格的项目结构被他们的数据目录:一个YAML文件,它指定输入和输出数据集如何以及在哪里被持久化。数据集可以存储在本地,也可以存储在云数据存储服务(如S3)中。

大约六个月前,我开始使用Kedro,从那时起,我就将它用于不同的实验数据管道。其中一些管道用于构建最终部署到生产中的模型,还有一些用于与团队成员的协作。下面,我将讨论我在Kedro中发现的优点和缺点,以及它如何帮助我们创建可重复、可维护的数据管道。

良好的

  • 再现性我在这里说的好话都不够:他们做到了。他们的依赖管理需要一点时间来适应,但它对所有依赖都强制使用特定的版本,这非常棒。还有,打字的能力kedro安装而且kedro运行执行整个管道是非常棒的。你仍然需要记住种子随机数生成器,但即使这样也很容易记住,如果你把它放在它们的params.yml文件。
  • 功能隔离Kedro的固定项目结构鼓励您考虑管道所需的逻辑步骤,并为每个步骤编写单个节点。因此,每个节点都趋向于短小(就代码行而言)和特定(就逻辑而言)。这使得每个节点易于编写、测试和稍后读取。
  • 开发并行:小节点也使开发人员更容易并发工作。很容易发现互不依赖的节点,并且可以由不同的人并发地对它们进行编码。
  • 中间数据:也许我最喜欢Kedro的是数据目录。只需将输出数据集的名称添加到catalog.yml然后嘭,它将被序列化到磁盘或云数据存储中。这使得构建管道变得超级简单:在一个节点上工作,提交它,执行它,并保存结果。它在团队工作时也很有用。我可以在大型GPU机器上运行一个昂贵的节点,并将结果保存到S3,另一个团队成员可以从那里开始。这都是与生俱来的。
  • 代码的可重用性:我承认我看过从来没有重复使用的笔记本。我充其量只是拿出一个旧的来提醒自己是如何完成一些复杂的分析的,但即使这样,我也必须记住数据的复杂性。然而,节点的隔离使得重用它们变得很容易。还有Kedro的支持模块化的管道(例如,将管道打包到PIP包中)使得共享公共代码变得简单。我们为图像处理等常见任务创建了模块化管道。

虽然Kedro已经解决了实验数据管道中的许多质量挑战,但我们注意到一些需要较少优雅工作的陷阱:

  • 增量数据集:这种支持用于读取数据,但对于写入数据集缺乏这种支持。当我们有一个节点需要8-10个小时才能运行时,这影响了我们几次。如果节点中途失效,我们就失去了功。类似地,如果结果数据集不适合内存,就没有保存增量结果的好方法,因为Kedro中的写入器假设所有分区都在内存中。这个GitHub问题如果开发人员解决了这个问题,可能会修复它,但现在你必须自己管理部分结果。
  • 管道的增长:管道很快就会变得难以理解,因为输入和输出只是数据目录中可能存在也可能不存在的命名变量。Kedro即这很有帮助,但是在导航器和代码之间切换有点烦人。我们还开始强制节点名称和它们的函数之间的名称一致,以及管道中的数据集名称和节点函数中的参数名称一致。最后,制作更多更小的管道也是保持理智的好方法。虽然所有这些技术都可以帮助您在精神上进行跟踪,但通过命名输入和输出来编码管道仍然需要权衡。
  • 可视化: Kedro并没有真正考虑到这一点,这是我认为笔记本电脑仍然有优势的一件事。然而,Kedro使您可以很容易地在笔记本中加载Kedro上下文,因此您仍然可以启动一个来进行一些可视化。最终,我希望Kedro能够更好地支持生成持久化到08_reporting层的图形化报告。现在我们通过创建一个将笔记本电脑渲染到磁盘的节点来解决这个问题,但这充其量是一种hack。我希望能够更好地支持生成最终的、高度可视化的报告,这些报告可以像中间数据一样在数据目录中进行版本控制。

结论

那么我是Kedro的皈依者吗?是的,你说对了。它取代了我过去用于实验数据管道和模型训练的bash脚本和Python笔记本的蜘蛛网,并使我们团队之间能够更好地协作。对我来说,它不会取代完全产品化的基于流的数据管道,但它绝对确保了我的实验管道是可维护的、可复制的和可共享的。

Hadoop应用的根本原因分析

Parth Shah和Thai Bui

概述

Hadoop作业难以操作的原因之一是它们无法为用户提供清晰的、可操作的错误诊断消息。这源于Hadoop由许多相互关联的组件组成的事实。当组件发生故障或行为不佳时,故障将级联到其依赖组件,从而导致作业失败。

本文试图通过创建一个用户友好的、自助的、可操作的Hadoop诊断系统来帮助解决这个问题。

我们的目标

由于其复杂的性质,该项目被分为多个部分。首先,我们创建了一个诊断工具原型,通过提供清晰的根本原因分析和节省工程时间来帮助调试Hadoop应用程序故障。其次,我们有意地在集群上施加故障(通过一种称为混沌测试的方法),并收集数据以了解某些日志消息如何映射到错误。最后,我们研究了正则表达式和自然语言处理(NLP)技术,以便在生产中自动提供根本原因分析。

为了记录这一点,我们将博客分为以下几个部分:

  • 错误消息分析门户
    • 快速浏览一下已知的根本原因。
  • Datadog仪表板
    • 计算未知根本原因和已知根本原因相关的故障率。
    • 将基础设施故障与丢失的数据故障(丢失的分区)分开。
  • 数据访问
    • 来自Yarn、Oozie、HDFS、hive server等服务的所有相关日志消息都被收集并存储在一个具有过期策略的S3桶中。
  • 混沌数据生成
    • 使用混沌测试,我们产生了与内存、网络等相关的实际错误。这样做是为了了解日志消息和根本原因错误之间的关系。
    • 创建了一个服务,以创建一种高效而简单的方式来运行混沌测试并收集其相应/相关的日志数据。
  • 诊断消息分类
    • 由于日志消息的简单和重复性质(低熵),我们构建了一个自然语言处理模型,对未知故障的特定错误类型进行分类。
    • 在Bazaarvoice的特定工作负载的混沌数据上测试模型

错误消息分析门户

Bazaarvoice为最终用户提供了一个管理分析应用程序的内部门户工具。下面的屏幕截图演示了“由于缺少数据而导致作业失败”的示例消息。此消息是通过使用堆栈跟踪的简单正则表达式捕获的。正则表达式之所以有效,是因为由于缺少数据,作业只有一种可能失败。



DataDog仪表板

什么是分区?

分区是一种基于日期、组件或其他类别将表划分为相关部分的策略。使用分区,可以更容易、更快地查询一部分数据。然而,在我们的设计中,作业正在查询的分区有时不可用,这将导致作业失败。下面的仪表板计算指标并跟踪由于不可用分区而失败的作业。

仪表板将失败的作业分类为分区失败(延迟/丢失数据)或未知失败(Hadoop应用程序失败)。我们的诊断工具试图找到未知故障的根本原因,因为数据延迟或丢失是一个很容易解决的问题。



数据访问

由于我们的集群是由Apache Ambari提供支持的,因此我们利用并增强了Ambari Logsearch Logfeeder,将相关服务的日志直接发送到S3,并按照下面目录树图中的raw_log对数据进行了分区。然而,随着数据集越来越大,分区不足以有效地查询数据。为了提高读取性能和迭代速度,后来将数据转换为ORC格式。



将JSON日志转换为ORC日志

DROP TABLE IF EXISTS创建外部表默认值。temp_table_orc(集群STRING,文件STRING, thread_name STRING,级别STRING, event_count INT, ip STRING,类型STRING,…s3a:/// ORC -log/${workflowYear}/${workflowMonth}/${workflowDay}/${workflowwhour}/';插入默认值。temp_table_orc SELECT * FROM bazaar_magpie_rook。rook_log WHERE year=${workflowYear} AND month=${workflowMonth} AND day=${workflowDay} AND hour=${workflowwhour};

根本原因诊断查询样例

SELECT t1.log_message, t1。logtime, t1。水平,t1。类型,t2。频率FROM (SELECT log_message, logtime, TYPE, LEVEL FROM (SELECT log_message, logtime, TYPE, LEVEL, row_number() over (partition BY log_message ORDER BY logtime) AS r FROM bazaar_magpie_rook。row_log WHERE cluster_name = 'cluster_name' AND DAY = 28 AND MONTH=06 AND LEVEL = 'ERROR') S WHERE S.r = 1) t1 LEFT JOIN (SELECT log_message, COUNT(log_message) AS Frequency FROM bazaar_magpie_rook. log WHERE cluster_name = 'cluster_name' AND DAY = 28 AND MONTH=06 AND LEVEL = 'ERROR')row_log WHERE cluster_name = 'cluster_name' AND DAY = 28 AND MONTH=06 AND LEVEL = 'ERROR' GROUP BY log_message) t2 ON t1.log_message = t2.log_message WHERE t1.log_messagelogtime BETWEEN '2019-06-28 13:05:00' AND '2019-06-28 13:30:00' ORDER BY t1。logtime LIMIT 400;

SELECT log_message, logtime, type FROM bazaar_magpie_rookrow_log WHERE level = 'ERROR' AND type != 'logsearch_feeder' AND logtime BETWEEN '2019-06-24 09:05:00' AND '2019-06-24 12:30:10' ORDER BY logtime LIMIT 1000;

SELECT log_message, COUNT(log_message) AS Frequency FROM bazaar_magpie_rook。log_log WHERE cluster_name = 'dev-blue-3' AND level = 'ERROR' AND logtime BETWEEN '2019-06-27 13:50:00' AND '2019-06-29 14:30:00' GROUP BY log_message ORDER BY COUNT(log_message) DESC LIMIT 10;

混沌数据生成

混沌数据的生成过程占了整个项目的很大一部分,也是最重要的一部分。它源于混沌测试的过程,在软件和基础设施上进行实验,以了解系统承受意外或动荡条件的能力。这种测试的概念是由Netflix在2011年首次提出的。下面的伪代码解释了它的工作原理。

通过特定集群上的API提交一个普通作业为该集群中的所有可测试节点(例如工作者节点)创建一个IP地址列表。一旦我们有了所有关联的节点,就向它们注入失败(压力测试内存或网络),而作业还没有完成,让作业运行。此时,作业要么失败,要么成功。停止所有压力测试收集作业的详细信息,如开始时间、结束时间、状态,以及最重要的相关压力测试类型(内存、packet_corruption等)。以JSON格式存储工作详细信息及其报告

工作报告示例

{"duration":"45分钟","nominalTime":"2018-10-27 07:00:00", "cost":0.7974499089253186, "downloadLinks":[], "errorMessage":"Error: "Error: " Main class [org.apache.oozie.action.hadoop. "Hive2Main],退出代码[2]","startTime":"2019-07-25 18:45:37", "stopTime":"2019-07-25 19:31:18","failedAction":"hive-action", "chaos_error":"packet_corruption", "workflowId":"0001998-190628043141230-oozie-oozi-W", "status":"KILLED"}

我们遵循相同的过程来生成不同类型的注入故障的混沌数据,例如:

  • 主机内存占用率过高
  • 包腐败
  • 包丢失
  • 容器上的高内存效用

虽然模型能够学习和分类的错误肯定更多,但出于原型设计的目的,我们将失败类型保留为2-3个类别。

诊断消息分类

在本节中,我们将探讨两种类型的错误分类方法,一个简单的正则表达式和监督学习。

用Regex短期解决方案

有许多方法可以分析不同模式的文本。其中一种方法称为正则表达式匹配(regex)。正则表达式是“表示搜索操作中要匹配的模式的特殊字符串”。regex的一个用途是查找关键字,如“partition”。当作业由于缺少分区而失败时,其错误消息通常如下所示:即使尝试了16次,也不是所有分区都可用”。这个特定情况的正则表达式是这样的\ W *((?我)分区(? -我))\ W *

正则表达式日志解析器可以很容易地识别这个错误,并采取必要的措施来修复这个问题。然而,当涉及到分析复杂的日志消息和堆栈跟踪时,regex的功能非常有限。当我们发现一个新的错误时,我们将不得不手动硬编码一个新的正则表达式来匹配新的错误类型,从长远来看,这是非常容易出错和乏味的。

由于Hadoop生态系统包括许多组件,因此可以产生许多日志消息的组合;简单的正则表达式解析器在这里很难工作,因为它不能处理不同句子之间的一般相似性。这就是自然语言处理的作用。

监督学习的长期解决方案

这个解决方案背后的思想是使用自然语言处理来处理日志消息,并使用监督学习来学习和分类错误。与正常语言相比,这个模型应该能很好地处理日志数据,因为机器日志更有结构,熵更低。你可以把熵看作是一组数据的非结构化或随机性的度量。由于英语的句子结构有时不合逻辑,相对于机器日志,英语往往具有高熵。另一方面,机器生成的日志数据非常重复,这使得建模和分类更容易。

我们的模型需要对日志进行预处理,这被称为标记化。标记化是将一组文本分解为单独的单词或标记的过程。接下来,使用Word2Vec在高维空间中建模它们之间的关系。Word2Vec是一种广泛流行的模型,用于学习单词的向量表示,称为“单词嵌入”(word2vec).最后,我们使用向量表示来训练一个简单的逻辑回归分类器,使用之前生成的混沌数据。下图显示了类似的训练处理经验报告:基于自然语言处理的日志挖掘及其异常检测应用Christophe Bertero, Matthieu Roy, Carla Sauvanaud和Gilles Tredan。



与上图相反,由于我们只在错误日志上训练分类器,因此不可能对正常系统进行分类,因为它不应该产生错误日志。相反,我们在不同类型的压力系统上训练数据。使用混沌测试生成的数据集,我们能够确定每个失败作业的每个错误消息的根本原因。这使我们能够使我们的训练数据集如下所示。我们将数据集分成简单的70%用于训练,30%用于测试。

随后,对每个日志消息进行标记以创建一个词向量。所有的标记都被输入到预训练的word2vec模型中,该模型将每个单词映射到向量空间中,创建单词嵌入。每一行表示为一个向量列表,日志消息中所有向量的平均值表示高维空间中的特征向量。然后,我们将每个特征向量及其标签输入到分类算法中,如逻辑回归或随机森林,以创建一个可以从对数线预测根本原因错误的模型。然而,由于失败通常包含多个错误日志消息,因此仅仅从一个长错误日志中的一行日志中得出根本原因的结论是不符合逻辑的。解决这个问题的一个简单方法是将日志窗口化,并将窗口中的各个行输入到模型中,并将最终错误作为窗口中所有行输出的最常见错误输出。这是一种非常幼稚的分离长错误日志的方法,因此必须进行更多的研究来处理错误日志,同时不失去对其相关消息的有价值的见解。

下面是错误日志消息及其标记版本的几个示例。

使用实例原始日志

java.lang.RuntimeException: org.apache.thrift.transport.TSaslTransportException:没有数据或没有sasl数据流org.apache.thrift.transport.TSaslServerTransport Factory.getTransport美元(TSaslServerTransport.java: 219)美元org.apache.thrift.server.TThreadPoolServer WorkerProcess.run (TThreadPoolServer.java: 269) java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java: 1149)美元java.util.concurrent.ThreadPoolExecutor Worker.run (ThreadPoolExecutor.java: 624) java.lang.Thread.run (Thread.java: 748)[: 1.8.0_191]引起的:org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:328) at org.apache.thrift.transport.TSaslServerTransport.open(TSaslServerTransport.java:41) ~[hive- exc -3.1.0.3.1.0.0-78.jar:3.1.0-SNAPSHOT] at org.apache.thrift.transport.TSaslServerTransport$Factory.getTransport(TSaslServerTransport.java:216)

标记化原始日志

[java,lang,RuntimeException,org,apache,thrift,transport,TSaslTransportException,No,data, No, sasl,data,stream,org,apache,thrift,transport,TSaslServerTransport,Factory,getTransport,TSaslServerTransport,java219] [org,apache,thrift,server,TThreadPoolExecutor,WorkerProcess,run,TThreadPoolServer,java,269]…

结果

该模型准确地预测了作业失败的根本原因99.3%我们测试数据集的准确性。乍一看,根据测试数据计算的指标看起来很有希望。然而,我们仍然需要评估其在生产中的效率,以获得更准确的情况。这个概念证明的初步成功证明了使用NLP对错误进行分类的进一步实验、测试和研究。

训练数据70%(前20行)

测试数据结果30%(前20行)

结论

为了在生产中实现这个工具,数据工程师必须将数据聚合和模型构建管道的某些方面自动化

自我报告错误

机器学习模型的好坏取决于它的数据。为了使这个工具健壮和准确,每当工程师遇到一个新的错误或一个模型不知道的错误时,他们应该报告他们对根本原因的信念,以便相应的错误日志被标记为特定的根本原因错误。例如,当一个作业由于类似的原因失败时,该模型将能够诊断并分类其错误类型。这可以通过一个简单的API、表单、Hive查询来完成,该查询包含作业id及其假设的root_cause。背后的想法是,通过创建一个表单,我们可以手动标记日志消息和错误,以防分类器无法正确诊断真正的问题。

自我报告的错误应该采取混沌错误的形式,以确保现有的管道能够正常工作。

自动化混沌数据生成

混沌测试应该定期进行,以保持模型的更新。这可以通过创建一个按常规节奏自动运行的Jenkins作业来实现。通常情况下,运行压力测试会使某些节点不健康。它导致我们的自动化无法再次SSH到节点以停止压力测试,例如当压力测试干扰到节点的连接时(参见下面的错误)。这可以通过为压力测试创建时间限制来解决,这样脚本就不必在任务完成后再次ssh。从长远来看,随着自报告误差的增长,模型应该减少对混沌测试的依赖。混沌测试为非常极端的情况生成日志,这可能不是正常生产环境的典型情况。

java.lang.RuntimeException:无法设置本地端口转发到10.8.100.144:22 at com. bazaarvoice.rook.infra.uti.remote.gateway .connect(Gateway.java:103) at com. bazaarvoice.rook.infra.regress.yarn.rootcausetest .kill_memory_stress s_test(RootCauseTest.java:174)

这家网站2019

今年的Bazzarvoice黑客松恰逢我们在奥斯汀举行的年度全体大会。我们的全球办事处花时间在专注于创新、社会整合和提高效率的项目上。我们各个部门的团队都参与其中,包括:研发、产品、客户服务和知识库。

黑客松团队花了两天时间来完成他们的项目。第二天,各团队在科学展上展示他们的成果,同时公司对项目进行投票。排名前十的团队接着向整个公司进行展示。

感谢所有参与的人,特别是组织各种活动的人。我们希望看到许多这样的项目成为新的产品增强。

响应API演示应用

您是否打算在此基础上开发自己的应用程序Bazaarvoice Response API?我们有东西要给你。的响应API演示应用是一个简单的Node-React应用程序,演示了如何将响应API与我们的3-leg OAuth2 API结合使用。建议您浏览开发人员门户网站并阅读相关内容OAuth2 API响应API在深入下面的应用程序架构之前。

这个应用程序是用创建React应用它由两个独立的组件组成前端客户端在React中后端服务器端在NodeJS。

让我们首先讨论一下后端体系结构。几乎所有的服务器端逻辑都包含在server.js.使用表达NodeJS框架,这个文件定义了以下端点:

  • / api /重定向-这个端点应该处理来自OAuth2的任何传入重定向,使用授权码(如果是第一次登录)或刷新令牌(如果现有的访问令牌已经过期或即将到期)获取访问令牌。如果您正在构建与OAuth2集成的应用程序,则必须定义一个端点以类似的方式处理重定向。
  • / api / check-login-这是一个特定于应用程序的端点,它的定义是为了客户端可以很容易地使用服务器验证用户是否登录,然后将他们带到登录页面。
  • 对响应API的GET、POST、PATCH、DELETE调用的抽象——这些端点基本上是响应API提供的端点的克隆在这里在开发者门户网站。这样一来,客户端就可以直接调用这些受保护的端点,而不必通过用户的浏览器公开任何OAuth2凭据。与获取和刷新OAuth令牌有关的所有逻辑都安全地保存在服务器端。

此应用程序使用express-session使用浏览器cookie存储和维护用户会话,这对于能够在不存储后端状态的情况下维护多个用户非常重要。但是,用户会话的这种实现不适合生产应用程序,您可能应该使用cookie和会话存储的组合来维护用户会话。

服务器端凭据和配置应该存储在服务器/ server-config.json然后由Node服务器接收。注意,这些凭证是机密的,不应该以任何方式暴露给客户端。

说到前端架构,我们使用反应图书馆和语义UI用户界面组件。客户端做了很多事情,从查询评论API的对话然后使用评审ID来获取/添加/修改/删除对该评审的相应响应响应API.前端的核心由以下组件组成:

  • 登录页面—如果用户没有登录(我们使用/ api / check-login我们将他们重定向到这个页面,这个页面有一个小部件,允许他们转到Bazaarvoice登录页面,输入他们的Bazaarvoice门户登录凭据,一旦他们被正确验证,OAuth2 API将他们重定向到/ api /重定向端点,然后处理所有令牌交换逻辑。在应用程序配置过程中,您可以将这个重定向URI配置为您想要的任何东西,但为了使演示应用程序按预期工作,它应该是http://localhost:5000/api/redirect正如您在配置文件中看到的那样。所有OAuth2登录和令牌交换过程都发生在这一步中。
  • 搜索页面-这个页面实际上是这个应用程序的登陆页面,用户可以在这里输入一个Review ID(可以使用Workbench或对话API获得),然后他们就会被带到Review页面。

  • 评论页面-一旦用户被验证,他们搜索一个有效的评论ID,他们被带到这个页面,通过调用获取指定的评论API的对话然后通过调用应用程序的后端来获取该审查的所有响应,而后端又调用响应API.因此,在这个页面上,用户可以看到评论的内容以及所有的回复。这还允许他们添加新的响应、编辑现有响应或删除响应。

您可能已经注意到响应上的department字段显示为下拉菜单。这些菜单选项已在演示应用程序中硬编码,可以在departmentFormOptions.js文件。此外,client.js是一个实用程序文件,它将所有常用的API调用作为客户端所有组件都可以访问的简单函数。

客户端配置存储在response-demo /客户/ src / config.js跑龙套文件。当前端客户端在运行前打包时,这是内置于项目中的。浏览器可以访问这些配置,因此不应该在这里存储任何机密信息。

除此之外,该应用程序遵循相当标准的体系结构,您可以阅读更多有关它的内容在这里.在部署方面,有一个Dockerfile它构建客户端构件,设置服务器并在本地环境中启动和运行应用程序。遵循这些指令让它在本地运行。该应用程序还可以部署到弗林通过更改配置中的重定向URI,并确保您的Flynn重定向URI被添加到应用程序凭据的允许重定向URI列表中。

Vger让你大胆地走…

你在一个敏捷团队工作吗?你很有可能是。无论你采用的是Scrum/看板/精益还是极限,你都是在尽可能少的阻力下完成工作。见鬼,如果你还在玩《Waterfall》,你就会关心这个问题。但你做得怎么样?你知道吗?这是开发人员或主管应该担心的事情吗?还是SEP?这是个刁钻的问题。如果您的团队被要求负责,并且他们的期望和您的交付之间存在差距,通过传递属性,您应该担心一些基本的精益度量。

在Bazaarvoice,我们是敏捷的,并且压倒性地利用看板。看板强调流程和持续改进的原则。为了对我们的改进做出数据驱动的决策,我们需要一种简单的方法来获取相关数据。仅通过JIRA和GitHub,访问正确的数据就有很大的进入障碍。

所以,像任何有进取心的工程师团队一样,我们为此开发了一个应用程序。

我们做了什么

我们中的一些人最近参加了一个优秀的精益指标预测研讨会专注目标公司的Troy Magennis.在他的培训中,他提出了展示精益指标象限的想法,以便为团队行为强制叙述,并避免过度使用单一指标。这真的引起了我的共鸣,似乎是我们想要构建的应用程序的一个很好的范例。

就这样,Vger诞生了。

我们使用了一个简单的象限视图,具有非常可书签的url参数。我们通过为团队提供一个界面来创建他们自己的“Vger团队”,并添加他们需要的任何“Vger板”,从而使团队的自助服务变得简单。从本质上讲,如果您可以创建一个JQL查询并在JIRA中为其提供一个板,Vger就可以为其绘制指标图。在显示中,我们通过让团队配置仪表板的日期范围、要显示的工作类型以及被视为工作/非工作的JIRA板列,提供了极大的灵活性。

现在,采用精益指标的门槛降低到了“你能不能打开浏览器”。不太寒酸。

象限视图

我们在象限视图中显示以下内容:

1.吞吐量-每周完成的票的数量。

2.变化——吞吐量的变化(标准偏差/平均值)。

3.积压增长-打开的票与关闭的票。

4.提前时间-完成票的提前时间。这也提供了一个详细的视图,通过Jira板列,看看你花了大部分时间在哪里。

我们Bazaarvoice是保守的赌徒,因此您将看到吞吐量和提前时间象限显示50%、80%和90%的可能性(与百分位数相反)。我们这样做是因为依赖平均水平或平均值对你不利。谁想掷硬币打赌?不是我们。我们希望自己十有八九是对的。

季度展望

后来,我们被要求按季度显示吞吐量,以帮助制定季度目标。我们为此创建了一个侧车页面。它按季度显示吞吐量:

我们还为交货时间建立了一个散点图,以便可以调查异常值:

该视图具有可缩放的区域,并且每个点都允许您单击到相应的JIRA票据。这很好。

但是等等!Git…

从第一天开始,我们选择为GitHub Pull Requests展示同一个象限。

注意,我们在PR Volume象限中显示了被拒绝和合并的行。我们还支持在PR和JIRA票据数据上叠加你的git标签。很甜!

我想做更多

Vger允许您从Quadrant和Quarterly视图下载吞吐量数据。您也可以从Quarterly视图中下载交货时间。这让团队和个人在这些非常有用的精益指标上执行他们自己的可视化和调查。

但是为什么呢?

Vger在构建时考虑了三个用例:

团队应该被告知

团队应该在他们的回顾中很容易获得这些关键的精益指标。我们建议他们从查看象限开始,看看他们是否同意复古主持人所呈现的叙述。他们还应该考虑他们所尝试的任何改进实验的结果。新的行为是否像他们希望的那样使吞吐量上升?新的行为是否会减少代码审查的时间?它是否减少了打开漏洞的数量?等。当然,并不是所有的复古都应该被无情的数据驱动,但它是持续改进文化的关键元素。

管理者应该了解这些数据,并与之交流

团队经理通常会谈论他们的团队是如何进步的。这些讨论应该是数据驱动的,最重要的是,它应该由团队可以访问的相同数据驱动(希望可以回溯到)。它还应该以一种仍然提供一些自定义的通用格式表示。注意:您应该避免在Vger或类似的可视化中比较团队。在大多数情况下,这种方式会导致徒劳、困惑和沮丧。

我们应该有数据来推动关于未来的数据驱动决策

然而,精益预测超出了本文的范围,特洛伊·马格尼斯对此有很好的见解我对这个问题的简单看法是:一个运行正常的团队,即使只有一点点运行时间,也不应该被问到“需要多长时间?”放弃低价值的例行公事,做高价值的分解工作,然后用历史数据进行预测。您可以方便地从电子表格中使用的Vger下载这些历史数据。我碰巧喜欢蒙特卡罗模拟我自己。

这不是看板吗?

您会注意到我自始至终都使用了术语“精益指标”。我想避免任何“看板vs scrum vs‘我们如何做事’”的下意识反应。无论您有意识地(或无意识地)为团队的工作流程使用什么方法,这些度量都适用。考虑到它是为功能开发团队构建的,但是当我们的客户实现团队作为早期采用者开始使用它时,我们取得了很好的成功。这使他们能够清楚地了解自己的交货时间细节,并找出等待客户执行某个操作的实际时间。

酷。我如何得到一个Vger?

我们在这里开源了请自便。这呈现为“它为我们工作”的软件,并没有像它可能的那样精细抛光,所以它有一些警告。这是一个非常简单的无服务器应用程序JIRA而且GitHub,所以目前只支持这些工具。如果你使用类似的,给Vger一试!

接下来是什么?

如果你很想投稿,这里有一些建议:

  • Vger的ETL流程真的需要更新了
  • 象限视图UI真的需要更新React来匹配季度视图
  • 使它对您所选择的问题跟踪器或源代码控制具有灵活性?
  • 如何添加一个漂亮的累积流程图?

测试时仍然看起来不错:使用可视化回归服务进行自动化测试(第二部分)

如果你经常关注我们的博客,你可能已经读过了我们关于使用视觉回归测试的帖子用于更好地测试应用程序前端外观的工具和服务。如果没有,请花几分钟阅读我们之前关于这个主题的文章。

现在,您已经了解了最新情况,让我们将在上一篇文章中所做的事情进行到下一个阶段。

在这篇文章中,我们将展示如何通过给定的测试服务(browserstack),以及通过Jenkins中提供给我们的选项更好地报告我们的测试。

调整模糊因子:

如果您在使用默认设置的可视化回归服务的多个浏览器上多次运行您的测试,您可能会注意到在diff目录中突然出现一些看起来几乎相同的异常图像。

browser-fight

浏览器战斗! !

如果您碰巧要跨多个浏览器(使用Browserstack或类似的服务)进行测试,这些浏览器可能托管在真实或虚拟环境中,屏幕分辨率相差很大,这可能会影响可视化回归服务执行图像差异比较的方式。

为了缓解这种情况,要么确保您的各种浏览器主机能够以相同的分辨率显示浏览器,要么稍微增加测试的不匹配容忍度。

正如我们在前一篇文章中提到的,你可以通过编辑项目wdio.conf文件中“visual regression service”对象下的值来做到这一点。例如:

visualRegression:{比较:新的VisualRegressionCompare。LocalCompare({referenceName: getScreenshotName(path.join(process.cwd(), '截图/参考')),screenshotName: getScreenshotName(path.join(process.cwd(), '截图/屏幕')),diffName: getScreenshotName(path.join(process.cwd(), '截图/diff')), misMatchTolerance: 0.25,}),

在上面的片段中,将不匹配容差值设置为0.25将允许回归服务在检查屏幕截图与它捕获的任何参考图像时有25%的误差幅度。

更好的测试结果:

在上一篇文章中也提到过,在我们的测试中使用视觉回归服务的例子的一个缺点是,除了图像比较的输出外,几乎没有反馈被返回。

head-in-sand

在缺乏反馈的情况下获得乐趣?

然而,通过一些额外的代码,一旦生成屏幕比较事件,我们就可以在测试执行中生成可用的断言语句。

关键是checkElement()方法,它实际上是一个WebdriverIO方法,由可视化回归服务增强。此方法返回一个对象,该对象包含关于为所提供的参数请求检查的一些元数据。

我们可以将方法调用分配给一个新变量,一旦我们将对象“反序列化”为可读的内容(例如JSON字符串),我们就可以利用Chai或其他框架使用断言来使我们的测试更具描述性。

这里有一个例子:

It ('should test some things visual ',() =>{…let returnedContents = JSON.stringify(浏览器。checkElement('<我的web元素>');console.log (returnedContents);断言。includes('<要断言的反序列化文本',返回contents);});

在上面的代码片段中,接近测试的结尾,我们调用' checkElement() '来对给定的web元素选择器的内容进行可视化比较,然后将' checkElement() '返回的对象转换为字符串。之后,我们断言在我们的比较返回的字符串化对象中有一些文本/字符串内容。

对于文本断言,我们希望断言一个成功匹配的消息包含在返回的对象中。这是因为' checkElement() '方法虽然可能返回指示测试失败的数据,但它本身不会触发异常,如果图像比较不匹配发生,则会导致测试失败。

添加移动

going-mobile

哦,有人下载了煎饼应用程序!

将WebdriverIO的框架与可视化回归服务和浏览器测试服务(如Browserstack)结合起来,我们可以创建针对真实浏览器运行的测试。要做到这一点,我们需要对WebdriverIO配置做一些更改。试试下面的方法:

  1. 复制你的wdio.conf.js
  2. 将副本命名为wdio.mobile.conf.js
  3. 编辑您的包。json文件
  4. 复制“scripts”下的“test”键/值对,并将其移到新行,重命名为“test:mobile”
  5. 将test:mobile脚本指向wdio.mobile.conf.js配置文件并保存更改

接下来,我们需要编辑wdio.mobile.conf.js脚本的内容,以只针对移动设备运行测试。添加一个完整的、新的测试配置和脚本声明的原因是,由于移动设备的行为方式,使用WebdriverIO和Browserstack进行移动浏览器测试需要声明一些设置,这些设置与在桌面浏览器上运行测试不兼容。

编辑移动配置文件顶部的代码块,将其更改为以下内容:

Var path = require('path');var VisualRegressionCompare = require('wdio-visual-regression-service/compare');函数getScreenshotName(basePath){返回函数(上下文){var类型= context.type;var testName = context.test.title;var browserVersion = parseInt(context.browser. var。版本,10);var browserName = context.browser.name;var browserOrientation = context.meta.orientation;返回路径。加入(basePath, ' $ {testName} _ {browserName} _v {browserVersion} _美元$ {browserOrientation} _mobile.png ');}; }

注意,我们已经删除了高度和宽度维度的声明。由于Browserstack允许我们在实际的移动设备上进行测试,定义视口约束不仅没有必要,而且会导致我们的测试无法执行(高度和宽度维度对象不能作为实际移动设备配置的一部分传递给webdriver)。

接下来,更新visual-regression服务的移动配置文件底部的方向配置如下:

朝向:['纵向','横向'],

由于使用响应式设计的应用程序在移动设备上从一个方向移动到另一个方向时可能会中断,因此我们希望在两种方向模式下运行测试。

在上面的配置中声明这种行为将触发我们的测试自动切换方向并重新测试。

最后,我们需要在这个配置文件中更新我们的浏览器功能设置:

能力:[{设备:'iPhone 8', '浏览器堆栈。local': false, 'realMobile': true,项目:'我的项目- iPhone 8',},{设备:'iPad 6 ', '浏览器堆栈。local': false, 'realMobile': true,项目:'我的项目- iPad',},{设备:'三星Galaxy S9', '浏览器堆栈。local': false, 'realMobile': true,项目:'我的项目- Galaxy S9',},{设备:'三星Galaxy Note 8', '浏览器堆栈。local': false, 'realMobile': true, project: 'My project - Note 8',},]

在上面的代码中,' realMobile '描述符是通过Browserstack对现代移动设备运行测试所必需的。有关这方面的更多信息,请参见Browserstack的文档

保存更改后,尝试通过以下操作在移动设备上运行测试:

NPM运行测试:移动

检查测试的图像输出,并将它们与桌面测试运行的结果进行比较。现在你应该能够在各种浏览器(移动和桌面)上运行应用UI的测试。

把东西拿给詹金斯

你可以将我们到目前为止放在一起的项目包含到应用程序的代码库中(只需从包中复制开发依赖项即可。Json你的规格和配置到现有的项目)。

另一种选择是将其作为一个独立的测试工具来应用一些基于屏幕截图的应用验证。

在下面的示例中,我们将详细介绍如何将这样的项目设置为Jenkins中用于测试给定应用程序并将结果发送给团队成员的资源。

考虑一下每次构建时生成一系列有针对性的应用元素屏幕截图,并将其发送给产品经理或UX设计师等团队成员的价值。从开发运营的角度来看,这并不一定是“繁重的工作”,但自动化应用的任何类型的反馈都将有助于交付更好、更快的应用。

假设你的项目托管在Github上,你对Jenkins有管理权限,你的应用托管在Jenkins可以访问的环境中(你组织的Amazon S3桶,托管在Docker镜像等):

I.创建一个新的Jenkins工作

jenkins-proj-name

*在构建和发布web应用的工作所在的空间内创建一个新的Jenkins任务(如果存在的话)。给它分配一个名称。

2将作业配置为从Github的图像测试应用程序中提取

jenkins-set-repo

*转到作业的源代码控制配置部分。为您构建的测试应用程序输入存储库的信息。

3将项目设置为定期生成

jenkins-set-trigger

*在作业的生成设置中,选择定期生成选项并配置作业的频率。

理想情况下,你应该将这个作业设置为在构建和“发布”你的应用程序的任务成功完成后触发(因此,每次发布应用程序的新版本时执行你的测试)。

或者,要根据给定的时间定期运行,然后在Jenkins的cron配置字段中输入' * 23 * * * '之类的内容,将作业设置为每天运行一次(在本例中,是在晚上11点,相对于服务器的配置)。

IV.构建shell执行脚本

jenkins-shell-script

*为您的任务创建一个构建步骤,并选择shell脚本选项。你可以在这里嵌入你的npm测试脚本执行。

收集你的神器

从后期构建选项列表中,选择' archive artifacts '选项。在可用的文本字段中,输入希望捕获的生成屏幕截图的路径。注意,根据Jenkins服务器的配置方式,此路径可能有所不同。如果您在精确定位工件的确切路径上遇到困难,可以在shell脚本步骤中回显' pwd '命令,让作业在作业的控制台输出中列出您的工作目录,然后从那里开始工作。

jenkins-archive

六、发送邮件通知

jenkins-email-config

*最后,从后构建选项菜单中选择高级电子邮件通知选项。

输入您希望在此工作完成后联系的电子邮件或电子邮件地址列表。填写您的电子邮件设置(主题行,正文等),并确保输入您希望附加到给定电子邮件的屏幕资源的路径。必威投注网

保存您的更改,您就可以开始了!

此作业将定期运行,执行一组给定的特定于UI的测试,并将屏幕捕获信息发送给希望了解这些信息的查询团队成员。

您可以创建更细致的运行,但使用Jenkins的克隆功能来复制此工作,更改为运行特定于移动设备的测试,使您的测试运行多样化。

进一步的阅读

如果您想深入研究可视化回归测试,网上有几个值得参考的代码示例。

此外,还有其他值得研究的可视化回归测试服务,例如珀西。IO过滤网。IO而且Fluxguard

测试时看起来很好:使用可视化回归服务进行自动化测试

很多(虚拟的)墨水已经洒在这个博客上关于自动化测试(不,真的).这篇文章是关于不同的自动化测试工具以及如何使用它们来交付更好、更高质量的web应用程序的系列文章中的另一篇。

在这里,我们将重点关注特定于的工具和服务'视觉回归测试——特别是应用程序前端的跨浏览器可视化测试。

什么?

通过可视化回归测试,我们指的是专门应用于应用程序外观的回归测试,这些外观可能会随着浏览器或时间的推移而发生变化,而不是功能行为。

为什么?

测试web应用最常见的起点之一是打开一个给定的浏览器,在测试环境中导航到应用,并注意外观上的任何差异(“哦,看,登录按钮颠倒了。是谁干的!?”)。

american_psycho

关于如何加强代码质量的一个辛辣的观点——我们不会讲到这里。

可视化回归测试的优势在于,您是在一组非常人性化的条件下测试应用程序的(应用程序在最终用户眼中是怎样的,以及它是怎样的应该看)。缺点是这样做通常是耗时和乏味的。但这就是我们有自动化的原因!

hamburger_ad_vs_reality

如何我们的汉堡呈现在Chrome vs如何它呈现在IE 11…

如何?

一位智者曾经说过,“在软件自动化中,没有这样的方法调用‘if != ugly, return true’”。

在大多数情况下,这种说法是正确的。在给定的浏览器支持矩阵下,完全自动化地测试web应用程序的外观,对于软件自动化问题,真的没有什么“银弹”。至少没有一些警告。

这样做的方法和工具可能与以下至少一种冲突:

  • 他们很昂贵(在时间、金钱或两者方面)
  • 他们很脆弱(测试会产生假阴性,可能不可靠)
  • 它们是有限的(只涵盖受支持的浏览器的一个子集)

faberge_egg

当然,您可以支持精巧的工具。只要记住总成本。

工具

我们将展示如何快速设置一组工具使用WebdriverIO,一些简单的JavaScript测试代码和可视化回归服务模块来创建应用程序前端的快照,并根据其外观执行测试。

设置

假设你已经有了一个web应用程序,可以在你选择的环境中测试(希望不是在生产环境中),并且你熟悉NodeJS,让我们开始编写我们的测试解决方案:

interesting_man_tests_code

这个梗太老了,我都不能…

1.在命令行中,创建一个新的项目目录,并按以下顺序执行:

  • ' npm init '(遵循初始化提示-可以使用默认值并稍后更新)
  • 安装-保存-dev webdriverio
  • ' npm install -save-dev wdio-visual-regression-service '
  • npm install -save-dev chai

2.一旦完成模块的安装,就需要配置WebdriverIO实例。您可以手动创建文件“wdio.conf.js”并将其放置在项目根目录中(请参阅WebdriverIO开发者指南关于在配置文件中包含什么),或者您可以使用wdio自动化配置脚本。

3.为了快速配置你的工具,在你的项目根目录下运行' npm run wdio '来启动自动配置脚本。在配置过程中,请确保选择以下内容(如果手动设置,则将其包含在wdio.conf.js文件中):

  • 在框架下,确保启用摩卡(我们将使用它来处理断言之类的事情)
  • 在services下,确保启用以下功能:
    • visual-regression
    • Browserstack(我们将利用Browserstack处理所有来自WebdriverIO的浏览器请求)

注意,在这种情况下,我们不会安装selenium独立服务或任何本地测试二进制文件Chromedriver.这个练习的目的是快速地将一些占用空间非常小的工具打包在一起,可以处理任何给定web应用程序前端的高级回归测试。

完成配置脚本后,您的项目中应该有一个wdio.conf.js文件,该文件已配置为使用WebdriverIO和可视化回归服务。

接下来,我们需要创建一个测试。

编写测试

首先,在项目的主源代码中创建一个名为tests/的目录。在该目录中,创建一个名为首页.js的文件。

设置文件内容如下:

description ('home page', () => {beforeEach(function () {browser.url('/');});it('应该看起来像预期的那样',()=> {browser.checkElement('#header');});});

就是这样。在单个测试函数中,我们调用了来自可视化回归服务的方法“checkElement()”。在我们的代码中,我们提供了ID, ' header '作为参数,但你应该用你想检查的页面上容器元素的ID或CSS选择器替换这个参数。

当执行时,WebdriverIO将打开它为我们的web应用程序提供的根URL路径,然后将执行它的检查元素比较操作。这将生成应用程序的一系列参考屏幕截图。然后回归服务将在每个浏览器中生成应用程序的屏幕截图,并在这些屏幕和参考图像之间提供一个增量。

更复杂的测试:

在你希望执行可视化回归测试之前,你可能需要明确你的web应用程序的一部分。还可能需要执行checkElement ()函数多次使用多个参数,以这种方式全面审查应用程序前端的外观和感觉。

幸运的是,由于我们只是通过WebdriverIO继承了可视化回归服务的操作,我们可以在测试中结合基于webriverio的方法调用来操作和验证我们的应用程序:

description ('home page', () => {beforeEach(function () {browser.url('/');});it('应该看起来像预期的那样',()=> {browser.waitForVisible('#header');browser.checkElement(“#头”);});它('应该看起来正常后,我点击按钮,()=> {browser.waitForVisible('.big_button');browser.click(“.big_button”);browser.waitForVisible(“# main_content”);browser.checkElement(“# main_content”);}); it('should have a footer that looks normal too, () => { browser.scroll('#footer'); browser.checkElement('#footer'); }); });

广泛关注与狭隘关注:

可能会增加这样的视觉测试的脆弱性的几个因素之一是试图解释视觉元素中的微小变化。这是一件很难同时兼顾的事情。

尝试检查一个大型且填充量很大的容器(例如body标签)的内容很可能包含跨浏览器的许多可能的变体,以至于您的测试总是会抛出异常。相反,试图将测试的重点缩小到一些非常边缘的东西(例如,选择单个按钮的单个实例)可能永远不会被前端开发人员实现的代码所触及,因此,你可能会错过应用程序UI的关键更改。

flight_search_results

这太多了,不能一次测试。

可视化回归服务的神奇之处在于,它允许你针对给定网页的特定区域或应用程序中的路径进行测试——基于Webdriver可以解析的web选择器。

price_link

这太少了…

理想情况下,你应该选择一个内容范围不太大也不太小,而是介于两者之间的网页选择器。一个专注于比较包含3-4个小部件的特定div标签的内容的测试,可能比一个专注于单个按钮的选择器或包含30个小部件或各种web元素的div的测试更有价值。

或者,你的一些应用前端可能是由模板或脚手架生成的,这些模板或脚手架从未收到更新,并且与你的团队频繁更改的代码隔离开来。在这种情况下,围绕这些方面编组测试可能会导致浪费大量时间。

精炼

但这是对的!

相应地选择你关注的领域。

回到手头的配置:

在运行测试之前,让我们对配置文件进行一些更新,以确保我们已经准备好运行初始的主页验证脚本。

首先,我们需要添加一些帮助函数来方便截图管理。在配置文件的顶部,添加以下代码块:

Var path = require('path');var VisualRegressionCompare = require('wdio-visual-regression-service/compare');函数getScreenshotName(basePath){返回函数(上下文){var类型= context.type;var testName = context.test.title;var browserVersion = parseInt(context.browser. var。版本,10);var browserName = context.browser.name;var browserViewport = context.meta.viewport;var browserWidth = browserViewport.width;var browserHeight = browserViewport.height;返回路径。join(basePath, `${testName}_${browserName}_v${browserVersion}_${browserWidth}x${browserHeight}.png`); }; }

这个函数将被用来为我们在测试期间将要拍摄的各种屏幕截图构建路径。

如前所述,我们在这个例子中利用Browserstack来最小化我们需要交付的代码量(假设我们希望将这个项目作为Jenkins任务中的资源),同时允许我们在可以测试的浏览器中具有更大的灵活性。要做到这一点,我们需要确保配置文件中的一些更改到位。

注意,如果您正在使用不同的浏览器供应服务(SauceLabs, Webdriver的网格实现),参见WebdriverIO的在线文档对于如何设置您的wdio配置为您各自的服务在这里)。

打开你的wdio.conf.js文件,确保这段代码是存在的:

用户:process.env。BSTACK_USERNAME, key: process.env。BSTACK_KEY,主机:'hub.browserstack.com',端口:80,

这允许我们通过命令行将浏览器堆栈身份验证信息传递到wdio脚本中。

接下来,让我们设置希望使用哪些浏览器进行测试。这也是在我们的wdio配置文件' capabilities '对象下完成的。这里有一个例子:

能力:[{browserName: 'chrome', os: 'Windows',项目:'My project - chrome', 'browserstack. '本地':false,}, {browserName: 'firefox',操作系统:'Windows',项目:'我的项目- firefox', '浏览器堆栈。local': false,}, {browserName: 'internet explorer', browser_version: 11, project: 'My project - IE 11', 'browserstack. local': false,}, {browserName: 'internet explorer', browser_version: 11Local ': false,},],

屏风应该放在哪里:

当我们在这里时,请确保您已经设置了配置文件,专门指向您希望将屏幕截图复制到的位置。可视化回归服务将想知道它将生成和管理的4种类型的截图的路径:

lots_a_screens

是的,太多屏幕了


参考文献:此目录将包含视觉回归服务在初始运行时生成的参考图像。这将是我们后续屏幕截图将与之进行比较的内容。

屏幕:此目录将包含测试生成的每种浏览器类型/视图的屏幕截图。

错误:如果给定的测试失败,应用程序将在故障点捕获图像并存储在这里。

差别:如果视觉回归服务在浏览器执行的元素和参考图像之间执行了一个给定的比较,结果导致差异,则将捕获并存储在这里的差异的“热图”图像。将此目录的内容视为您的测试异常。

事情变得模糊:

问好

法兹,不是福兹

最后,在开始测试之前,我们需要在wdio.conf.js文件中启用可视化回归服务实例。这是通过向配置文件中添加一段代码来完成的,该代码块指示服务如何运行。下面是一个摘自WebdriverIO开发者指南的代码块示例:

visualRegression:{比较:新的VisualRegressionCompare。LocalCompare({referenceName: getScreenshotName(path.join(process.cwd(), '截图/参考')),screenshotName: getScreenshotName(path.join(process.cwd(), '截图/屏幕')),diffName: getScreenshotName(path.join(process.cwd(), '截图/屏幕')),misMatchTolerance: 0.20,}), viewportChangePause: 300, viewports:[{宽度:320,高度:480},{宽度:480,高度:320},{宽度:1024,高度:768}],朝向:['portrait'],},

将此代码块放在文件中的“services”对象中,并根据需要编辑它。请注意以下属性,并根据您的测试需求进行调整:

“视窗”:
这是一个JSON对象,提供用于测试应用程序的宽度/高度对。如果你的应用程序有特定的响应式设计限制,这是非常方便的。对于每一对,测试将在每个浏览器上执行——为每一组尺寸调整浏览器的大小。

“方向”:这允许您配置测试以使用纵向和/或横向视图(如果您碰巧在移动浏览器中测试的话)执行(默认方向是纵向)。

“viewportChangePause”:在指示服务更改视口大小的每个点上,该值以毫秒为单位暂停测试。您可能需要根据应用程序在不同浏览器中的性能来限制这一点。

“mismatchTolerance”:可以说是最重要的设定。这个浮点值定义了“模糊因子”,服务将使用它来确定参考和屏幕截图之间的视觉差异应该在什么时候失效。默认值0.10表示,如果给定的屏幕截图与参考像素的差异为10%或更多,则会生成一个差异。数值越大,容忍度就越大。

完成配置文件的修改后,让我们执行一个测试。

运行测试:

如果您的配置文件被设置为指向项目中测试文件所在位置的根,则编辑您的包。Json文件,并在文件的脚本部分修改“test”描述符。

设置如下:

”。/ node_modules /。bin / wdio / wdio.desktop.conf.js '

要从命令行运行测试,请执行以下操作:

' BSTACK_USERNAME= BSTACK_KEY= npm run test - - baseurl = '

现在,坐好,等着测试结果出来。如果这是您第一次执行这些测试,那么在试图通过Browserstack捕获各种浏览器的初始引用时,可视化回归服务可能会失败。您可能需要在第一次运行时增加测试的全局超时,或者在这种情况下只需重新运行测试。

审核结果:

如果您习惯了标准的JUnit或jest风格的测试执行输出,那么这里的测试输出就不一定类似。

如果在测试过程中出现功能错误(您试图检查的对象在屏幕上不可用),将生成一个标准的基于webdriver的异常。然而,除此之外,您的测试将通过—即使在视觉上检测到差异。

但是,请检查我们前面提到的屏幕截图文件夹结构。注意已经生成的文件的数量。打开其中的几个,看看在通过Browserstack测试时,通过ie11和Chrome捕获了什么。

请注意,文件后面附加了名称,用于描述它们对应的浏览器和视口尺寸。

例二

来自特定浏览器的屏幕截图示例

注意是否生成了“Diff”目录。如果是,检查一下它的内容。这些是您的测试结果——具体地说,是您的测试失败。

example2

一个不同的图像的例子

对于我们在这里设置的基本工具集,还有许多其他选项可供探索。然而,我们将在这里暂停,并沉浸在能够使用5-10行代码执行这种级别的浏览器测试的美妙之中。

还有吗?

这篇文章实际上只是触及了使用一组可视化回归测试工具所能做的事情的表面。使用这些工具还有很多选择,比如启用移动测试,改进错误处理,并将其与构建工具和服务相匹配。

我们希望在以后的文章中更深入地讨论这些主题。现在,如果您正在寻找额外的阅读材料,请随意查看其他一些关于可视化回归测试的相关文章在这里在这里而且在这里

审计您的Web应用程序的可访问性与灯塔

如果您关注了我们的博客一段时间,您可能会遇到详细介绍如何进行各种软件测试的帖子,从性能数据驱动的安全和更多。

这篇文章延续了这一趋势,重点是测试你的网站的可访问性。

无障碍是什么?

所有门禁卡

如果你不熟悉这个概念,可访问性,在web应用领域是一个涵盖广泛问题的术语。主要的重点是编纂和帮助加强设计标准,以确保所有人都能访问web -无论人们的消费和交互能力如何。

这是一个非常大的主题,其定义超出了本文的意图范围。如果你正在寻找一个起点,我们的朋友在W3C.org我可以帮你:https://www.w3.org/standards/webdesign/accessibility

如果您想开门见山,有两个主要的可访问性标准您应该知道(并且通常被认为是实现遵从性的途径)。这两个都是W3C作为国际标准支持和覆盖的,可以在这里完整地查看:

你也可以参观这个链接获取一些相关的编码示例。

为什么易访问性?

为什么每个人都应该关注易访问性设计问题?简短的答案可以从Tim Berners-Lee爵士那里找到,通过W3C:

“网络的力量在于它的普适性。
无论残疾与否,每个人都能获得机会是一个重要方面。”

一个更复杂的答案是,随着网络在全球范围内的普及,我们作为软件开发者需要考虑所有用户访问网络的需求范围。这是一种公平的竞争,因为网络技术已经成熟,在我们的日常生活中变得越来越重要。不考虑可访问性也会产生法律后果。下面是一些例子:

我的网站有多容易访问?

的设计原则WCAG 2.0,那么您的web应用程序前端应该与大多数现代辅助软件(如屏幕阅读器)兼容。然而,如果不坐下来使用浏览器、应用程序、第三方工具和一些老式的手动测试,就很难验证应用程序的最终用户体验。

这样做的挑战——你可能已经想到了——是费时费力的。如果您在一个小型软件团队中,或者有一个非常紧迫的截止日期(或两者兼有),这种级别的手动测试可能是您的产品团队难以接受的(但必须的)药丸。

有第三方服务可以为您执行此级别的测试。快速谷歌搜索能让你走上这条路。然而,如果雇佣第三方在逻辑上或财务上都无法达到,有很多软件工具可以帮助消除可访问性验证的痛苦。

Chrome是你的朋友(真的)?

截至本文,谷歌的Chrome浏览器目前约占所有浏览器的1/2全球浏览器使用情况在网上。然而,Chrome不仅流行,它也有很多有用的工具在引擎盖下,以帮助web开发。

事实上,你可以使用基本的桌面版Chrome浏览器,对恰巧在浏览器中打开的某个站点进行可访问性审计。要尝试这个技巧,只需执行以下步骤:

  • 打开浏览器到要审计的给定站点
  • 打开Chrome开发者工具控制台
  • 在开发人员控制台选项卡下,(例如,网络、元素、控制台等)搜索并单击审计选项卡。
  • 单击“执行审计”选项,选择“辅助功能”,然后单击“运行审计”开始。

Chrome a11y审计截图

看看我们在引擎盖下找到了什么!

在这种情况下,审计工具将在您打开的当前URL上扫描站点的内容,以寻找支持可访问性标准的标记模式(例如,适当的元素命名约定,css设置等),并在页面上的标记中标记违反这些标准的模式。这些当然是基于本文开头提到的WCAG和AIRA约定。

这是一个功能强大但非常易于访问和运行的web开发人员工具集(你可以执行多种审计,而不仅仅是可访问性审计)。事实上,您可能会认为一定有一种方法来编程这些工具(您是对的)。

灯塔照明无障碍!

一旦你在Chrome中开始审计,你可能会注意到一条消息,上面写着一些叫做灯塔正在启动,在执行审计之前。

灯塔实际上,是执行审计的引擎。它还可以作为库依赖项使用,甚至可以作为自己的独立项目使用。

Lighthouse可以以多种方式集成到项目前端或构建周期中。其中之一是使用Lighthouse作为一个独立的分析工具,你可以用它来验证你的web应用程序部署后的前端(把它看作是另一组具有不同的、特定类型输出的功能测试——在这种情况下,是一个可访问性报告。

你可以通过以下命令行快速让Lighthouse在本地运行(假设你安装了NodeJS):

1.打开一个新终端,NPM安装-g lighthouse
2.一旦安装了最新版本的灯塔,lighthouse "url选择" -GA -output html -output -path ./report.html

一旦上面的命令执行并完成,您可以在web浏览器中本地打开Lighthouse report.html:

灯塔的报告

灯塔的报告

深入到报告的不同部分,看看你在可访问性(或性能,SEO或其他web标准)方面遵循了哪些最佳实践,以及你应该在哪些方面改进应用程序。

詹金斯配置

Lighthouse的Jenkins配置

要在CI构建过程中包含此报告,只需将上述Node命令行语句添加到附加到所选作业的shell脚本中,并确保将结果存档(如果在Jenkins任务中配置此操作,则作业配置可能看起来像这样:)

可访问性产品毛羽吗?

默认情况下,Lighthouse提供的报告是可扩展的,可能需要一段时间才能读完。

幸运的是,有几种方法可以将这种形式的测试向前推进。在本例中,我们将研究一个名为Lightcrawler

Lightcrawler允许您在NodeJS项目中调用Lighthouse的特定审计方面。这样做的好处是,在将项目交付到CI流程的其余部分之前,您可以更具体地针对要审计的内容并执行上述审计。

您可以简单地将Lightcrawler安装到您的项目中安装-save-dev lightcrawler

接下来,假设您的Node应用程序配置了一个脚本,该脚本将在本地生成和运行应用程序,只需将其添加到应用程序包的“scripts”部分。json文件:

" audit:a11y ": "./node_modules/.bin/lightcrawler——url=http://localhost:8080——config lighthouse-config.json",

使用Lightcrawler,您可以以多种方式配置可访问性审计,以满足您的项目需求。出于本文的目的,我们将配置Lightcrawler,使其只运行可访问性审计中分类的测试,并运行当前可用的该类型的所有测试。下面是我们的配置文件:

{"extends": "lighthouse:default", "settings": {"crawler": {"maxDepth": 1, "maxChromeInstances": 5}, "onlyCategories": ["Accessibility"], " only审计":["accesskeys", "aria-allowed-attr", "aria-required-attr", "aria-required-parent", "aria-required- children ", "aria-roles", "aria-valid- attrr -value", "audio-caption", "button-name", "bypass", "color-contrast", "definition-list", "dlitem", "document-title", "duplicate-id", "frame-title", "html- hash -lang", "html-lang-valid", "image-alt", "input-image-alt", "lable", "layout-table", "link-name", "list", "list-item", "meta-refresh", "meta-viewport", "object-alt", "tabindex", "td-headers-attr","th-has-data-cells", "valid-lang", "video-caption", "video-description"]}}

您可以复制上面的JSON,并将其保存为项目目录中的lightcrawler.conf.js,并将脚本指向配置文件的路径。

测试新添加的审计脚本,但该脚本正在运行NPM运行审计:a11y.如果一切正常,您应该会收到一个命令行输出,详细说明Lightcrawler执行的审计数量,以及任何给定的可能失败的审计测试的错误输出(更重要的是,为什么会失败)。

Lightcrawler控制台输出

Lightcrawler控制台输出

这看起来类似于检测报表输出或者ESLint.类似于在项目中的预提交钩子中使用pretty或ESLint的方式,你可以在预提交钩子中添加Lightcrawler脚本,以更好地保护应用程序代码免受可能的易访问性侵犯。

超越审计和检测!

这应该会给你一些想法,让你知道如何在保持可访问性的同时,减少交付应用程序web前端所需的整体工作。这里提供的技巧绝对不足以完全涵盖可访问性伞下的所有内容。这项任务将需要大量的时间和精力,但是,为了保持网络的包容性和连接性的最初意图,我们作为软件开发人员应该努力实现。

依赖安全性和NodeJS入门

网络安全是一个越来越受关注的话题。如果你是在2018年初读这篇文章,问题是崩溃幽灵Equifax违反一定还记忆犹新。

网络安全是一个巨大的问题,似乎势不可挡。你从哪里开始呢?你要去哪里?如果您是一个资源有限的小型应用程序团队,该怎么办?必威投注网如何在考虑安全性的情况下更好地设计项目?

讨论这个主题的完整格式塔(包括OWASP等)超出了本文的范围。但是,如果您参与的是一个小型前端团队,并且如果您利用AWS等服务,那么您已经经历过OWASP清单你在想,‘现在怎么办?’,这篇文章是为你准备的(特别是如果你正在用NodeJS开发,我们将在这篇文章中重点介绍)。

让我们来谈谈Co(de)依赖关系:

一只老虎和她的小猪宝宝

我们说的是被抚养人,对吧?

我们可以快速影响应用程序安全性的一种方法是通过更好的依赖项管理。无论你是用Python、JavaScript、Ruby还是像Java和c#这样的编译语言开发,库包和模块都是你工作流程的一部分。

当然,是3理查德·道金斯但这并不意味着它不会对您的项目产生重大影响(每个人都应该记住Leftpad折磨就在几年前)。

事实证明,应用程序的依赖关系可能是应用程序最大的依赖关系脆弱性。

管理不是你写的代码:

下面,我们将概述一些步骤,您可以采取这些步骤来处理安全开发的至少一个方面——依赖项管理。在本文中,我们将介绍如何在标准NodeJS项目中实现一些有用的工具,以保护、修复和警告可能通过依赖项堆栈引入应用程序的潜在安全问题。

你的代码有问题

我们都不得不在某个时候处理别人的有问题的代码

使用依赖性检查:

即使你不使用NodeJS,如果你正在构建任何继承一个或多个库的项目,你应该为该项目设置某种形式的依赖项检查。

对于NodeJS应用程序,依赖性检查是您可以更好地保护开发过程的最简单、最容易摘到的果实。

依赖性检查是一个命令行工具,可以扫描你的项目,并警告你的任何模块被包含在你的应用程序的清单,但实际上没有在任何功能代码中使用(例如模块列在你的包。Json文件,但在你的应用程序中的任何类中从来没有“必需”)。毕竟,为什么要导入不需要的代码呢?

安装是小菜一碟。在你的项目目录中,你可以:

Npm install -g dependency-check依赖检查包。json未使用

如果您有未使用的包裹,依赖性检查将通过以下通知提醒您:

失败!包中的模块。jsonnot used in code: chai, chai-http, mocha

有了手头所有未使用包的列表,您就可以在将应用程序推向生产环境之前对其进行修剪。这个工具可以在您的CI流程中触发,每次提交到master,甚至可以合并到项目的预提交钩子中,以进一步扫描应用程序。

RetireJS:

俗话说:“你要什么,你就得退休”——至少在退休的时候是这样RetireJS.退休是一套工具,可用于各种类型的应用程序,以帮助识别您的应用程序合并的依赖关系,已知的安全漏洞。

退休适用于一般的基于JavaScript的项目,而不仅仅是NodeJS框架。

出于本文的目的,并且由于我们主要处理命令行,因此我们将使用退休的CLI部分

NPM install -g退休

然后从你的项目的根源开始:

退休

如果你只扫描一个NodeJS项目的依赖项,你可以使用以下参数缩小扫描范围:

退休-nopdepath

默认情况下,该工具将返回如下内容,前提是你有RetireJS可以识别的漏洞:

ICanHandlebarz/test/jquery-1.4.4.min.js↳jquery 1.4.4。min有已知漏洞:http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-4969 http://research.insecurelabs.org/jquery/test/ <a href="http://bugs.jquery.com/ticket/11290">http://bugs.jquery.com/ticket/11290 < / >

退休扫描你的应用程序,并将其中使用的包与更新的在线数据库的包/包版本进行比较,这些包/包版本已被安全世界识别为具有可利用代码。

请注意,上面的扫描输出显示,我们通过ICanHandlebarz模块导入的jquery版本有一个漏洞,可以被黑客利用(请注意链接到cve - 2011 - 4969——问题中的漏洞)。

有了这个列表,我们可以识别应用程序中任何不必要的依赖项,以及任何可以利用的漏洞,因为我们目前正在导入和使用的代码。

规划:

在网络上有许多针对NodeJS应用程序的包扫描实用程序。其中,规划的(节点安全平台)可以说是最受欢迎的。

前面提到的退休是一个适用于JavaScript项目的依赖项扫描程序,规划的,顾名思义,是专门为Node应用程序设计的。

前提是相同的:这个命令行工具可以扫描你的项目的包清单,并识别任何已知的web漏洞,可以利用3理查德·道金斯你在应用中包含的派对包。

利用规划的和“退休”听起来可能有些多余,但是,就像通过医疗专业人员诊断严重疾病一样,寻求其他意见通常是值得的。使用NSP启动和运行也同样容易:

npm install -g nsp nsp check - Report <

在节点应用程序的根目录中运行上述程序,将生成您选择的输出格式的报告

同样,将其连接到CI作业应该很简单。您甚至可以使用退休和NSP执行背靠背扫描。

Snyk:

是的,这是另一个依赖项扫描器——就像NSP一样,另一个专门面向NodeJS的扫描器,但有一个额外的扭曲:Snyk

Snyk主页

Snyk主页

使用退休和NSP,我们可以快速自由地生成应用程序能够利用的漏洞列表。然而,补救呢?如果您有一个大型Node项目,可能无法快速修补或整理依赖关系问题,该怎么办?这就是Snyk会派上用场。

Snyk可以生成详细而美观的报告(非常适合那些可能不深入了解项目代码的团队成员)。该服务还提供了其他功能,如自动邮件通知和监控应用程序的依赖问题。

典型Snyk报告

典型Snyk报告

成本:现在,这些功能听起来很棒(听起来也很贵)。Snyk是一项免费服务,取决于应用程序的大小。对于小型项目或开源应用程序,Snyk基本上是免费的。对于有较大需求的团队,您将希望咨询他们的当前的价格

安装和运行与Snyk,第一次访问https://snyk.io并注册一个用户帐户(如果你在github或bitbucket中有一个私有或开源项目,你会想要用你的代码管理工具的帐户注册你的Snyk帐户。

接下来,在命令行控制台的项目根目录下:

NPM install -g snyk snyk -auth

通读控制台提示符。一旦您收到成功消息,您的项目现在已经准备好向Snyk帐户报告。下一个:

Snyk测试

一旦Snyk完成,您将呈现一个URL,将引导您到一个报告,其中包含Snyk能够找到关于您的项目的所有脆弱依赖信息。

该报告很方便,因为它不仅识别了漏洞和与之相关的包,而且还确定了补救步骤(例如,将给定的包更新到特定版本,删除它,等等)。

Snyk还有一些锦囊妙计。如果你想一头扎进保护你的申请。简单地运行:

Snyk向导

这将以交互式向导模式重新扫描应用程序,引导您浏览每个易受攻击的包,并提示您对每个易受攻击的包采取的操作。

注意,不建议在处理大规模应用程序时使用Snyk的向导模式,因为它非常耗时。

它看起来是这样的:

Snyk监控器输出

Snyk监控器输出

此外,您可以利用Snyk的监控功能,除了扫描您的应用程序,将发送电子邮件通知您或您的团队时,有更新与您的项目相关联的易受攻击的包。

把它们放在CI中:

当然,我们将把这些工具以某种形式安排到CI实例中。为什么不呢?考虑到我们有一系列易于实现的命令行工具,将它们添加到项目构建过程的一部分应该很简单。

下面是一个shell脚本的例子,我们在Jenkins作业中添加了一个构建步骤来安装和运行这些扫描工具,并输出它们对我们的作业可以存档的工件的一些响应:

安装我们的工具npm install -g snyk npm install -g dependency-check npm install -g退休#运行依赖检查并将结果输出到一个文本文件dependency-check ./package。json>> depcheck_results.txt #Runs retire and outputs results to a text file retire --nodepath node_modules >> retire_results.txt #Authenticates use with Snyk snyk auth $SNYK_TOKEN #Runs Snyk's monitor task and outputs results to a test file snyk monitor >> snyk_raw_monitor.txt #Uses printf, grep and cut CLI tools to retrieve the Snyk report URL #and saves that URL to a text file printf http: >> snykurl.txt grep https snyk_raw_monitor.txt | cut -d ":" -f 2 >> snykurl.txt cat snykurl.txt #Don't forget the set your post-job task in your CI service to save the above .txt #files as artifacts for our security check run.

注意:根据您在CI服务中如何部署应用程序的构建生命周期,您可能希望在作业中将上述脚本分解为单独的脚本或完全分开的作业。例如,你可能想在每次提交时使用Dependency-Check扫描你的应用程序,但只在应用程序每晚构建或部署到登台环境时使用NSP或Snyk保存你的应用程序扫描。在这种情况下,您可以相应地划分这个脚本。

关于Snyk的说明:

为了在你的CI实例中使用Snyk,你需要在执行这个工具时引用你的Snyk身份验证密钥(参见脚本中的API密钥引用)。

此键可以作为静态字符串传递给作业。您的认证密钥Snyk可以通过登录Snyk获得。在Snyk的主菜单中单击My account链接后,从帐户设置页面中检索API密钥。

下一个步骤:

当涉及到安全和web应用程序开发时,这只是冰山一角。希望本文为您提供了一些从哪里开始编写更安全软件的思路和方法。有关如何保护基于node的应用程序的更多信息,这里有一些额外的阅读:

为协作域创建实时响应式应用程序

抽样是Bazaarvoice的一种产品,允许消费者加入社区并领取限量的免费产品。必威手机版本作为回报,消费者为他们的样品提供诚实和真实的产品评论。必威手机版本必威手机版本产品在同一时间发布给消费者进行评论。这导致了对这些产品的争相认领。必威手机版本这是协作域问题的一个例子,许多用户试图对相同的数据进行操作(如Eric Evens书中所讨论的那样)领域驱动设计).

Bazaarvoice每年举办两次为期两天的黑客马拉松。员工可以自由地利用这段时间探索他们感兴趣的任何技术或想法。从我们的黑客马拉松活动中,Bazaarvoice开发了重要的新功能和产品,如我们的广告平台和个性化功能。必威手机版本Bazaarvoice 2017.2黑客松,贝尔法斯特团队演示了使用近实时状态同步来解决这一协作域问题的解决方案。

Bazaarvoice使用反应+回来的用于我们的前端web开发。这些库使用单向数据流和不可变状态管理的概念。这意味着始终有一个真实的来源,即存储,并且对于如何改变应用程序状态没有任何困惑。通常,我们使用副作用库redux-thunk通过HTTP API调用在服务器和客户端之间同步状态。这里的问题是,单向同步并不是被动的。客户端可以告诉服务器改变状态,反之则不行。在数据一直在变化的协作领域中,接近实时的同步对于确保良好的用户体验至关重要。

为了解决这个问题,我们决定使用谷歌的Firebase平台。该解决方案提供了许多无缝协同工作的功能,例如OAuth身份验证、CDN托管和Realtime DB。关于Firebase需要注意的重要一点是,它是一个后端即服务的项目,在这个项目中没有后端代码。

实时数据库在数据库的节点上提供一个发布/订阅模型,这允许客户端始终保持最新的状态。使用Firebase Realtime DB有一个重要的概念不容忽视,数据只能通过它的键(点查询)访问。

您可以将数据库看作云托管的JSON树。与SQL数据库不同,它没有表或记录。当您向JSON树添加数据时,它将成为现有JSON结构中的节点,并具有相关的键(参考)

这家网站的目标

  1. 实时可配置UI
  2. 实时竞选管理和参与
  3. 现场演示到整个公司为上述两种

实时可配置UI

在黑客马拉松演示中,我们演示了通过管理门户更新应用程序的风格和内容,这将允许客户端对应用程序进行风格调整以适应他们的品牌。这些更新被实时推送到从贝尔法斯特到奥斯汀(4608英里外)的50多个客户端设备上。

实现跨客户端状态同步的代码非常简单!

鉴于react的性质,一旦收到样式配置更新,每个设备都只是“反应”。

实时竞选管理和参与

在演示中,我们为现场活动添加了40个产品。必威手机版本这将40种产品推送到管理屏幕和必威手机版本50+移动应用程序。然后参与者被指示认领产品。

管理视图

成员的观点

所有成员都通过OAuth提供商(Facebook, Github或Gmail)进行身份验证。

令我惊讶的是,现场演示进展顺利。我很高兴添加....我的团队赢得了“技术”类的黑客马拉松。

结论

Firebase是一个愉快的工作,一切都按照预期工作,它在现场演示....中表现出色甚至在他们的免费层。Firebase中使用的模式对于更正统的工程师来说有点不合常规,但如果您的目标是快速开发,那么Firebase是其他任何平台都无法比拟的。Firebase实时数据库为运行采样活动提供了一个很棒的用户体验。虽然Firebase不会在产品中使用,但它为讨论实时数据同步的好处和可能性提供了很好的背景。

几年前,我会坚持认为web开发是软件工程的蛮荒西部;正在制定的解决办法没有纪律,也缺乏坚实的框架作为基础。它似乎没有任何我认为与良好的工程实践有关的特征。快进到今天,我们现在有丰富的工具,库和技术,使web开发感觉理智。

近年来,前端开发人员已经接受了诸如单向数据流、不可变性、纯函数(没有隐藏的副作用)、异步编码和线程并发等概念。我很好奇这些相同的概念是否会在后端开发中流行起来node . js作为后端语言继续发展。