政务网站集约化建设难点与建议怎样成立一个网站

张小明 2026/3/12 3:31:41
政务网站集约化建设难点与建议,怎样成立一个网站,抖音代运营方案范文,建设官网流程本文为Algolia公司软件工程师的实践分享#xff0c;Algolia公司总部位于旧金山#xff0c;打造“搜索即服务”平台#xff0c;为商家提供站内搜索引擎定制。 以下为作者观点#xff1a; 不久前#xff0c;我#xff08;作者#xff09;看到社区里有个说#xff1a;你…本文为Algolia公司软件工程师的实践分享Algolia公司总部位于旧金山打造“搜索即服务”平台为商家提供站内搜索引擎定制。以下为作者观点不久前我作者看到社区里有个说你会用哪三个词吓唬产品经理。在这些精彩的回复中有 还有一件事、差不多完成了、那是遗留代码还有可能被低估的 我测试过了。最后一句话让我记忆犹新因为它可能是最可怕的一句话。它引出了更多的问题你是如何测试的是否涵盖了所有的边缘情况测试是否与实际使用情况相符测试是否只检查了预期结果测试是否涵盖了更改是否会破坏应用程序中的其他功能下面就根据我们团队的经验来回答这些问题本文中主要探讨自动化测试的两种主要类型。单元测试 Unit testing在开始构建单元测试之前我们不妨退一步问问为什么需要单元测试。一般来说我们要确保应用程序正常运行单元测试只是验证程序是否正常运行的一小段代码。要理解单元测试是如何做到这一点的首先要认识到现代开发涉及模块化将功能拆分成尽可能小的部分。一旦我们将大型任务分割成这些小函数其中许多函数将恰好是纯函数在输入相同的情况下总是返回相同输出的确定性函数不会影响函数之外的任何事物也不会受到函数之外任何事物的影响。这些特性使得纯函数的测试变得简单明了因为我们只需模拟这些函数的使用方式然后检查输出是否与预期一致即可。这就是我们所说的 单元测试用假数据使用我们要测试的函数几次确保得到正确的结果。例如以著名的 Sigmoid 函数为例它是用 Python 编写的下面有一个简单的单元测试import mathdef sigmoid(x):return 1 / (1 math.exp(-x))def test_sigmoid():assert sigmoid(0) 0.5assert 0.9999 sigmoid(10) 1assert 0.2689 sigmoid(-1) 0.269assert sigmoid(-100000000000000000) 0果然最后一行揭示了我们代码中的一个错误。谁会想到 Python 的数学库 math library 无法处理像 -100000000000000000 这样的数字呢事后看来这对我来说是显而易见的我们输入 math.exp 的正数版本略微超出了 double 的范围但我之前并没有想到这一点这个小错误充分说明我们不可能了解我们工具的所有知识。尽管这里的公式在技术上是正确的但我使用的工具无法处理处理如此大的数字的边缘情况。值得庆幸的是如果我们给 math.exp 一个负数输入 sigmoid 时输入的是正数因为我们给 math.exp 输入的是-xmath.exp 可以很好地处理这个问题因为结果只是四舍五入为 0但如果 x 是正数我们就需要用稍微不同的方法来编写函数def sigmoid(x):if x 0:return 1 / (1 math.exp(-x))else:ex math.exp(x)return ex / (1 ex)现在我们的单元测试返回时不会触发任何警报如果我们的项目经理碰巧想到了一个我们没有想到的边缘情况那么在测试函数中添加另一个断言也是轻而易举的事。如果我们的测试函数并不纯粹呢这里有一个办法重构一个新的纯函数尽可能减少不纯函数中的内容。例如这个 JavaScript 函数在运行凯撒密码Caesar cipher之前从 DOM 获取一个字符串值​​​​​​​const runCaesarCipherOnInput () {const input document.getElementById(input);const result document.getElementById(result);const key 4;result.innerText input.value.toUpperCase().split().map((letter, i) {const code input.charCodeAt(i);if (65 code code 90) {let n code - 65 key;if (n 0) n 26 - Math.abs(n) % 26;return String.fromCharCode((n % 26) 65);} else return letter;}).join();};这很有效但是由于所有这些原因它很难进行单元测试。它不是确定性的也就是说对于给定的输入函数并不总是返回相同的输出而且还包含一些超出函数范围的副作用。甚至 .map 调用中的内部循环函数也不纯粹我们该如何解决这个问题呢让我们先试着把所有导致函数不纯的东西都清除掉只留下一些容易测试的功能然后再把这些部分重新构建成原始函数。​​​​​​​const caesar (msg, key, rangeStart65, rangeEnd91) msg.split().map(letter shiftLetter(letter, key, rangeStart, rangeEnd)).join();const shiftLetter (letter, key, rangeStart, rangeEnd) {const rangeLength rangeEnd - rangeStart;const code letter.charCodeAt(0);if (rangeStart code code rangeEnd) {let n code - rangeStart key;if (n 0) n rangeLength - Math.abs(n) % rangeLength;return String.fromCharCode((n % rangeLength) rangeStart);} else return letter;};const runCaesarCipherOnInput () {const input document.getElementById(input);const result document.getElementById(result);const key 4;result.innerText caesar(input.value.toUpperCase(), key);};请注意在这个示例中我们仍有两个不纯函数第3行输入 .map 的函数和 runCaesarCipherOnInput。不过这些函数非常简单不需要进行测试它们实际上并不执行任何逻辑它们的存在主要是为了向纯函数提供参数常量声明和 DOM 读取也非常简单易懂因此我们可以放心地认为它们会做我们想做的事情。如果使用 for 循环而不是 map我还可以做得更多但这里的重点是创建单元测试通常不需要开发人员做出大的改动。这次小小的重写达到了同样的目的它更容易阅读而且现在是可测试的--像 caesar 和 shiftLetter 这样的重要逻辑位都是纯函数所以我们可以像以前一样为它们编写断言测试这些函数应该放在与逻辑对应的地方为了更方便地进行批量测试将单元测试打包成逻辑组甚至使用专门的单元测试框架来处理模板可能会有所帮助。但是如果我们要测试的东西不那么容易封装在函数中会发生什么情况呢使用简单的单元测试来测试 UI 元素和整个工作流程就不那么简单了。下一步该怎么做请看下面的内容模拟整个浏览器。浏览器模拟 Browser emulation在上文中我们谈到了单元测试如何帮助我们轻松测试我们的函数以及如何让使用单元测试的思维方式首先帮助我们编写更纯粹、更简单、更模块化的函数。但是当我们需要测试一个不适合函数的系统时会发生什么呢如果我们不能依赖函数的输出来判断它是否工作该怎么办如果我们的函数依赖于用户界面设置的状态呢在这些情况下我们很难准确模拟用户如何浏览应用程序的复杂性--如果没有一个有用的抽象或简化方法供我们测试我们可能只能启动一个网站的实时实例假装自己是用户。我们肯定不能将这一过程自动化对吗这样做似乎太手工太依赖人脑了。事实证明解决方案并不在于自动化应用程序内部的任何操作而在于自动化浏览器的输入模拟你的鼠标和键盘这样你测试的应用程序就无法将模拟器与真人区分开来。这一过程被称为浏览器自动化。Chromium 项目提供了一个名为 Puppeteerhttps://pptr.dev/的应用程序接口我们将使用它来实现浏览器自动化。Puppeteer - 一个 headless 浏览器第一步是用开发实例启动并运行我们的网站因为我们想在投入生产前测试这些东西。由于这里只是演示我将在 Algolia 的生产主页上运行此测试。接下来我们将设置一个 Node.JS 程序。为此选择一个合理的位置可能是项目根目录下的一个文件夹以便与构建过程集成。在该文件夹中您需要创建一个调用所有测试的 index.js 文件。这样只需从 repo 的根目录运行 node test就能运行所有测试还能深入文件夹运行更具体的测试。现在在某些情况下在构建过程结束时将其作为构建后命令可能是合理的但这些将是更复杂的测试你可能希望手动运行所以如果你在本地开发和测试最好将其放在那里让你的开发人员在实际要运行 Puppeteer 测试时手动运行 node test 或 node test/specific-test.js。如果你的应用程序具有更复杂的构建流程涉及本地测试较少而云中开发实例较多那么建立一个无服务器项目Vercel 和 Netlify 都擅长此道可能会更容易将其设置为以 lambda 函数读取测试然后修改测试以便在你 ping 该端点时运行。实际上测试并不需要与应用程序在同一地点运行因为测试是完整的客户端所以你可以用一些按钮制作一个小小的图形用户界面在云中触发每个测试。运行 npm install puppeteer 后你需要一些模板代码。下面是一个示例测试的结构它将以我的身份登录 Algolia 并获取某个应用程序的凭据​​​​​​​const puppeteer require(puppeteer);const login async ({width, height}) {const browser await puppeteer.launch();const page await browser.newPage();await page.goto(https://algolia.com);await page.setViewport({width,height,deviceScaleFactor: 1});// test logic hereawait browser.close();};module.exports async () {login({width: 375,height: 667});login({width: 1150,height: 678});};;简单介绍一下第一行只是导入 Puppeteer。Puppeteer 由 Chromium DevTools 团队运行因此基本上是该生态系统的原生部分。在这里导入 Puppeteer 会链接到 Chromium 的无头版本即假装有图形用户界面的版本由于它是与 Chromium 同步开发的因此该版本能保证与 Puppeteer 配合使用。第一个函数名为 login用于运行我们的测试。现在这里没有任何测试逻辑只有启动无头 Chrome 浏览器、访问 Algolia 网站并将视口设置为我们传入函数的内容的模板。最后我们关闭浏览器使其不会在内存中保持打开状态。然后我们导出一个函数在不同尺寸的屏幕上运行相同的测试。要从测试文件夹中的 index.js 内运行该测试我们只需运行 require(./login)(); 即可。有了这种单行测试设置我们甚至可以将测试分组成批并通过命令行上的标志如 node test --dashboard 来触发这些批次。这里的自定义功能是无限的因此请根据你的应用需求进行调整。在我的应用中只要测试失败我就会抛出错误而不用担心批处理的问题因为我的测试还不够多集中精力在这里没有意义。不过在你的应用程序中让这些测试函数返回测试结果而不只是在测试失败时抛出错误可能会有所帮助因为这样你就能根据从 index.js 运行的测试打印出更详细的信息。现在我的目标是让一切都静默运行除非出现我们需要修复的问题。让我们深入了解一下实际的测试逻辑它可以说比你想象的要简单​​​​​​​// step 0. accept cookies so the site works like normalawait page.waitForSelector(a[href/policies/cookies/] button);await page.click(a[href/policies/cookies/] button);// step 1. wait for the log in link to appear and click on itif (width 960) {await page.waitForSelector([data-mobile-menu-button]);await page.click([data-mobile-menu-button]);}await page.waitForSelector(a[href/users/sign_in]);await page.click(a[href/users/sign_in]);// step 2. wait for the email input to appear on the new page, focus on it, and type the email from .envawait page.waitForSelector(input[typeemail]);await page.focus(input[typeemail])await page.keyboard.type(process.env.email);// step 3. focus on the password input, and type the password from .envawait page.focus(input[typepassword])await page.keyboard.type(process.env.password);// step 4. click the log in buttonawait page.click(form#new_user button[typesubmit]);// step 5. if were on mobile, well need to click one more button to indicate wed like to stay on mobileif ((await page.url()).includes(mobile)) {await page.waitForSelector(.continue-button);await page.click(.continue-button);}// step 6. wait for the application selector to appear and click itawait page.waitForSelector(#application-select);await page.click(#application-select);// step 7. click on the application with the name in .envawait page.$$eval(div span.options,(options, applicationName) {const matchedOptions options.filter(option option.innerText.split(\\n)[1] applicationName);if (matchedOptions.length) {matchedOptions[0].click();} else {console.log(Application ${applicationName} does not exist);}},process.env.applicationName);// step 8. wait for the api keys button to appear on the new page, and click itawait page.waitForSelector(#overview-api-keys-link);await page.click(#overview-api-keys-link);// step 9. wait for the page to load and get the application id and public api key for this projectawait page.waitForSelector(#api-keys-page-heading);const [applicationID, publicAPIKey] await page.$$eval(input[readonly],inputs inputs.slice(0, 2).map(input input.value));// step 10. log the results of our testif (applicationID ! process.env.applicationID)throw Application ID is not correct. Test produced ${applicationID}, but it should have been ${process.env.applicationID};if (publicAPIKey ! process.env.publicAPIKey)throw Public API key is not correct. Test produced ${publicAPIKey}, but it should have been ${process.env.publicAPIKey};// step 11. close the browserawait browser.close();这并不是一个微不足道的例子--如果你阅读了过程中每一步上面的评论你就不会感到太惊讶了。从字面上看这只是模仿用户在真实浏览器中的行为同时考虑到 Algolia 主页处理移动端与桌面端的不同之处。与之配套的是一个 .env 文件我在其中定义了登录时使用的电子邮件和密码、目标应用程序的名称用户将使用该名称找到正确的应用程序以及测试应返回的 publicAPIKey 和 applicationID。如果一切顺利则不会输出任何信息。如果出现故障它会抛出一个描述性错误这样我们就能在构建完成前及时修复。那么我们在这个系列中学到了什么测试主要有两种类型单元测试这是简单、纯粹、不与外界交互的函数的完美测试。即使是不纯粹的函数中的纯粹部分也可以隔离开来这样就可以在测试代码的同一文件中使用简单的断言对其进行单独测试这是一种很好的做法。浏览器模拟对于较大的工作流程需要让你的测试真正假扮成用户因此我们启动了名为 Puppeteer 的无头 Chromium 版本傀儡 一个假用户并走完整个流程浏览器甚至不知道它在与另一个程序交互。应该注意的是这些方法并不相互排斥--在 Algolia 面板上向开发者显示正确 API 凭据的这一特殊功能非常重要因此需要用这两种方法进行测试。我们已经编写了一个 Puppeteer 程序从用户的角度对整个工作流程进行演练但除此之外对我们从 API keys 页面搜刮的水合过程进行分解也很有帮助。如果我们在该页面中分离出尽可能多的纯函数就可以通过单元测试对它们进行测试确保该流程的绝大部分都不会发生静默中断。由于要从数据库中提取数据并显示在视图中因此可能无法做到完全纯净但这正是使用两种测试方法的好处我们不必使用任何一种方法获得 100% 的覆盖率。只要能同时覆盖所有内容我们就能对应用程序的耐用性和长期可持续性充满信心。感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴上万个测试工程师们走过最艰难的路程希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

做报价在哪个网站询价鄂州第一官方网站

第一章:云边 Agent 延迟优化的背景与挑战 在现代分布式系统架构中,云边协同计算逐渐成为支撑实时性要求高、数据量大的关键应用场景的核心模式。边缘节点负责就近处理终端请求,而云端则承担全局调度与深度分析任务。在此架构下,云…

张小明 2026/3/10 16:32:14 网站建设

新蔡哪有做网站建设的网上开小店怎么开

第一章:Open-AutoGLM 操作等待重试机制概述 在分布式系统与自动化任务调度中,网络波动、服务瞬时不可用或资源竞争等问题可能导致操作失败。Open-AutoGLM 引入了操作等待重试机制,以提升任务执行的鲁棒性与成功率。该机制通过智能退避策略和条…

张小明 2026/3/10 16:32:16 网站建设

网站建设职业怎么样网站规划建设书

大数据领域数据中台与传统数据架构的对比 引言 背景介绍 在当今数字化时代,数据已成为企业最宝贵的资产之一。随着业务的不断拓展和数据量的爆炸式增长,如何高效地管理、处理和利用数据,成为企业面临的关键挑战。数据架构作为企业数据管理的基…

张小明 2026/3/10 16:32:17 网站建设

淘客网站推广免备案wordpress子页面都转到首页

"为何渴求港股二次上市?" 作者 | 王冲和 编辑 | 卢旭成 前不久,安克创新正式向港交所递交了主板上市申请,这个“充电宝第一股”再次被世人关注。 早在2020年8月24日,安克创新已经登陆深交所创业板,上市首…

张小明 2026/3/10 16:32:19 网站建设

网站建设原则应考虑哪些wordpress 4.3

过去 20 年,企业组织的讨论几乎绕不开一个关键词:“协作”。跨部门协作、扁平化协作、敏捷协作、虚拟协作团队……每一波管理潮流,都在试图回答同一个问题:如何让人更高效地一起工作?然而 2025 年以后,这个…

张小明 2026/3/10 16:32:21 网站建设

备案ip 查询网站查询太原网站建设vhuashi

Logto终极指南:从零构建现代化身份认证系统 【免费下载链接】logto logto-io/logto: 这是一个用于收集、分析和可视化日志数据的Web工具。适合用于需要收集、分析和可视化日志数据的场景。特点:易于使用,支持多种日志格式,具有实时…

张小明 2026/3/10 16:36:49 网站建设