<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CharlyAutomatiza</title>
    <description>The latest articles on DEV Community by CharlyAutomatiza (@charlyautomatiza).</description>
    <link>https://dev.to/charlyautomatiza</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1266231%2F6761b424-b40c-4f0c-a115-ff868e6cd17e.png</url>
      <title>DEV Community: CharlyAutomatiza</title>
      <link>https://dev.to/charlyautomatiza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charlyautomatiza"/>
    <language>en</language>
    <item>
      <title>From One Skill to a Plugin: My Story Behind the Initial Release of grafana-k6-plugin</title>
      <dc:creator>CharlyAutomatiza</dc:creator>
      <pubDate>Tue, 31 Mar 2026 01:46:01 +0000</pubDate>
      <link>https://dev.to/charlyautomatiza/from-one-skill-to-a-plugin-my-story-behind-the-initial-release-of-grafana-k6-plugin-50og</link>
      <guid>https://dev.to/charlyautomatiza/from-one-skill-to-a-plugin-my-story-behind-the-initial-release-of-grafana-k6-plugin-50og</guid>
      <description>&lt;h2&gt;
  
  
  It started with a feeling I could not ignore
&lt;/h2&gt;

&lt;p&gt;Some ideas do not arrive as a polished product vision. They arrive as discomfort.&lt;/p&gt;

&lt;p&gt;I was spending more and more time working with LLMs inside developer workflows, and while the speed was impressive, I kept running into the same problem: the output often looked better than it actually was. The code was fluent, but not always trustworthy. The suggestions were fast, but not always current. The answers sounded confident, but that confidence was not always backed by real engineering judgment.&lt;/p&gt;

&lt;p&gt;If you are new to the concept, skills are folders of instructions, scripts, and resources that Claude and other agents can load dynamically to perform better on specialized tasks.&lt;/p&gt;

&lt;p&gt;In the k6 world, that gap matters a lot.&lt;/p&gt;

&lt;p&gt;For anyone new to it, &lt;a href="https://grafana.com/oss/k6/" rel="noopener noreferrer"&gt;k6&lt;/a&gt; is Grafana's open-source performance testing tool for load, stress, and reliability testing of APIs and services.&lt;/p&gt;

&lt;p&gt;I was seeing models suggest deprecated code, outdated references, and quality patterns that might pass a superficial review but would never feel solid if you actually cared about long-term maintainability or performance realism. Models could generate code very easily - that did not mean they were generating the right code for the real problem.&lt;/p&gt;

&lt;p&gt;As a Grafana k6 Champion with a strong performance engineering background, I knew the tool had enormous potential. I also knew a lot of that potential was being left on the table.&lt;/p&gt;

&lt;p&gt;The real value is not just generating a test script. The real value is being able to ask: is this scenario realistic? Are these thresholds meaningful? Is this auth flow being handled safely? Is this a recommendation I would actually trust in front of a team?&lt;/p&gt;

&lt;p&gt;I did not want to build something that simply made LLMs produce more code.&lt;br&gt;
I wanted to build something that helped them produce better decisions.&lt;/p&gt;


&lt;h2&gt;
  
  
  At first, I thought this would be a single skill
&lt;/h2&gt;

&lt;p&gt;The original idea was smaller. I was not thinking about a plugin. I was thinking about a skill.&lt;/p&gt;

&lt;p&gt;I wanted to condense my practical experience into something reusable - something that could guide an agentic IDE toward stronger k6 outputs, better defaults, and more reliable performance testing behavior.&lt;/p&gt;

&lt;p&gt;That first idea made sense for a while. A single skill felt elegant. Compact. Easier to reason about.&lt;/p&gt;

&lt;p&gt;But as I kept building, I ran into a reality that changed the whole direction of the project. Once the idea started growing, putting too much responsibility into one skill would reduce precision instead of increasing it.&lt;/p&gt;

&lt;p&gt;That is where a very old lesson came back to me.&lt;/p&gt;

&lt;p&gt;In my first year at university, one of the ideas that stayed with me was the classic divide and conquer mindset: break complexity into clearer, specialized parts, make each part excellent at its own job, reduce ambiguity by reducing responsibility overlap.&lt;/p&gt;

&lt;p&gt;That is exactly what this project needed.&lt;/p&gt;

&lt;p&gt;So the idea stopped being "one smart skill" and became something much better: a plugin built around three dedicated skills, each one focused, specialized, and expert in its own job.&lt;/p&gt;

&lt;p&gt;Instead of asking one giant skill to plan, build, validate, clarify, and reason about every edge case equally well, I could design a system where each part had a clearer mission and a tighter behavior contract.&lt;/p&gt;

&lt;p&gt;That was the moment the project became more than an experiment.&lt;/p&gt;


&lt;h2&gt;
  
  
  I was not trying to outgenerate LLMs, I was trying to outguide them
&lt;/h2&gt;

&lt;p&gt;This is probably the most important thing to understand about why I built grafana-k6-plugin.&lt;/p&gt;

&lt;p&gt;I was never trying to compete with LLMs at generation speed. Almost any model can produce code with a decent prompt today - that is no longer the hard part. What interested me was something deeper: how to inject more judgment into the generation process. How to make the output aligned with current platform realities, aware of performance engineering tradeoffs, and resistant to fragile assumptions.&lt;/p&gt;

&lt;p&gt;And especially: guided by expert questions when critical information is still missing.&lt;/p&gt;

&lt;p&gt;That last part became one of the foundations of the plugin. I did not want skills that would guess when they should ask. I wanted skills that would know when not to guess.&lt;/p&gt;

&lt;p&gt;In performance engineering, there are doubts that are negotiable and doubts that are not. If I do not know the target, the workload shape, the auth constraints, or the SLA expectations, I do not want a confident hallucination. I want the right question asked at the right time.&lt;/p&gt;

&lt;p&gt;When uncertainty is critical, the skill should ask like an expert. And the human should remain the one making the decision.&lt;/p&gt;

&lt;p&gt;That is not a weakness in the workflow. That is the workflow.&lt;/p&gt;


&lt;h2&gt;
  
  
  Learning about AskUserQuestion changed how I thought about skill design
&lt;/h2&gt;

&lt;p&gt;One of the moments that pushed this idea forward came from something very practical.&lt;/p&gt;

&lt;p&gt;My colleague Alan showed me the AskUserQuestion capability in Claude Code during a skills hackathon we had at work. That may sound like a small detail, but for me it clicked immediately.&lt;/p&gt;

&lt;p&gt;Because suddenly the interaction model was not just "generate the answer." It became: detect what is missing, stop at the right moment, and ask the right thing.&lt;/p&gt;

&lt;p&gt;That opened a much more powerful path. It meant I could build skills that behaved less like autocomplete with extra steps and more like a real specialist working alongside me.&lt;/p&gt;

&lt;p&gt;The hackathon itself was part of the spark too. Seeing what people were building, how quickly a good idea could evolve into something tangible, and the energy of people discovering new ways to package judgment and domain expertise into agentic workflows - that pushed me further. It made me feel that this plugin was worth building for the wider ecosystem, not just for myself.&lt;/p&gt;


&lt;h2&gt;
  
  
  When I stopped relying on intuition and started building evidence
&lt;/h2&gt;

&lt;p&gt;At some point, every ambitious build hits the same wall.&lt;/p&gt;

&lt;p&gt;You can feel that you are improving things. You can believe the structure is getting stronger. But eventually, feeling is not enough.&lt;/p&gt;

&lt;p&gt;I needed evidence. And this is where Anthropic's skill-creator workflow became fundamental for me - not just as a creation aid, but as part of an evaluation discipline.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/anthropics/skills/blob/main/skills/skill-creator/SKILL.md" rel="noopener noreferrer"&gt;Skill Creator from Anthropic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://resources.anthropic.com/hubfs/The-Complete-Guide-to-Building-Skill-for-Claude.pdf" rel="noopener noreferrer"&gt;The Complete Guide to Building Skill for Claude&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That meant designing evals, running them in structured iterations, comparing with-skill and without-skill behavior, using multiple agents where useful, and gathering empirical evidence instead of relying on taste.&lt;/p&gt;

&lt;p&gt;The difference in quality of decisions was significant.&lt;/p&gt;

&lt;p&gt;Before that, improvements sounded like: "this feels cleaner," "this looks more robust," "this answer reads better." After I started working through evals and comparisons, the conversation became sharper: "this iteration actually improved ambiguity handling," "this change is attractive but does not improve outcomes," "this needs a correction plan, not another vague rewrite."&lt;/p&gt;

&lt;p&gt;I also wanted to pressure-test the skills under real conditions: HTTP cases, gRPC scenarios, browser-oriented flows, script validation issues, safety and quality edge cases, and guidance quality under incomplete inputs. Not just ideal prompts. Multi-agent execution helped simplify comparison and made it easier to see whether a behavior was genuinely robust or just accidentally tuned to one narrow interaction pattern.&lt;/p&gt;

&lt;p&gt;When you are deep inside a project, doubt never disappears. But evidence gives doubt a productive direction. It turns anxiety into diagnosis and makes solid correction plans possible - the kind that say: this is the weak spot, this is the reason, this is the adjustment, and this is how we will know if it worked.&lt;/p&gt;

&lt;p&gt;That kind of loop creates trust. Not only in the artifact, but in the process itself.&lt;/p&gt;


&lt;h2&gt;
  
  
  Review was another turning point, and it was not always comfortable
&lt;/h2&gt;

&lt;p&gt;Before each PR, I kept iterating my PR review prompts. I did not want review to be a last-minute checkbox. I wanted it to be a designed stage with real value.&lt;/p&gt;

&lt;p&gt;GitHub Copilot review was genuinely important in that stage. It surfaced useful issues, accelerated feedback loops, and gave me another layer of signal before merging.&lt;/p&gt;

&lt;p&gt;But it also taught me something very important: good review support is not the same as full understanding.&lt;/p&gt;

&lt;p&gt;One example captured the problem perfectly. Inside the skill references, I had DO and DONT examples. The DONT examples were intentional - educational anti-patterns that existed so the skills could recognize poor practices and steer people toward better ones.&lt;/p&gt;

&lt;p&gt;At times, Copilot review identified those DONT examples as mistakes that should be corrected. From a pattern-matching point of view, that reaction made sense. From a human intent point of view, it was wrong.&lt;/p&gt;

&lt;p&gt;Without professional judgment, it becomes easy to "fix" the wrong thing. You can clean up the signal that was supposed to teach the model. You can make the final system more fragile while convincing yourself you improved it.&lt;/p&gt;

&lt;p&gt;That is not a theoretical risk. I saw versions of it happen.&lt;/p&gt;

&lt;p&gt;This is one of the strongest lessons from the project: our role as professionals is not optional. I do not see human-in-the-loop as a fallback. I see it as part of the architecture.&lt;/p&gt;


&lt;h2&gt;
  
  
  Ship before you disappear into endless polishing
&lt;/h2&gt;

&lt;p&gt;By the time I reached the initial release, the feeling was not "this is finished forever." It was something more grounded: this is now solid enough to put in front of the community and learn in public.&lt;/p&gt;

&lt;p&gt;That is an important distinction.&lt;/p&gt;

&lt;p&gt;I do not believe in waiting for some mythical state of perfection before sharing useful work. If I had waited for the moment when every possible improvement was already solved, this plugin would probably still be sitting in an endless spiral of iteration. There is always one more refactor, one more rule, one more benchmark, one more prompt tweak.&lt;/p&gt;

&lt;p&gt;At some point, you have to stop polishing in private and step onto the field.&lt;/p&gt;

&lt;p&gt;You have to ship.&lt;br&gt;
You have to ask for feedback.&lt;br&gt;
You have to let the real world respond.&lt;/p&gt;

&lt;p&gt;I fully expect there to be opportunities for improvement - I actually want that. I hope people open PRs. I hope the project keeps evolving. But I believe deeply in finishing stages: close one chapter, learn from it, and continue.&lt;/p&gt;

&lt;p&gt;That is healthier than living forever inside an unfinished draft.&lt;/p&gt;


&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;My repo:&lt;br&gt;
&lt;a href="https://github.com/charlyautomatiza/grafana-k6-plugin" rel="noopener noreferrer"&gt;https://github.com/charlyautomatiza/grafana-k6-plugin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installation&lt;/p&gt;

&lt;p&gt;Add this marketplace to Claude&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add charlyautomatiza/charlyautomatiza-marketplace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install a plugin from the marketplace&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin &lt;span class="nb"&gt;install &lt;/span&gt;grafana-k6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install directly from the plugin repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add charlyautomatiza/grafana-k6-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, you have three specialized skills available, each one with a clear role:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;k6-plan&lt;/strong&gt;: turns your objective into a concrete test strategy before code generation.

&lt;ul&gt;
&lt;li&gt;"Plan a load test for my users API."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;k6-builder&lt;/strong&gt;: creates runnable k6 artifacts from your requirements or from a plan.

&lt;ul&gt;
&lt;li&gt;"Generate a runnable k6 script for my checkout API."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;k6-validate&lt;/strong&gt;: reviews an existing script and prioritizes what to fix.

&lt;ul&gt;
&lt;li&gt;"Review this k6 script and flag the top issues that could make results unreliable."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Across all three skills, if required context is missing, the agent will pause and ask the right questions before continuing.&lt;/p&gt;

&lt;p&gt;Each one knows when to ask before it acts.&lt;/p&gt;

&lt;p&gt;If you are curious about how I built and evaluated these skills, the Anthropic skill-creator workflow is the same workflow I used.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build something, test it honestly, and put it out into the world
&lt;/h2&gt;

&lt;p&gt;If there is one thing I hope people take from this story, it is this: do not underestimate what happens when you combine domain expertise, agentic tooling, and a serious feedback loop.&lt;/p&gt;

&lt;p&gt;Code generation is no longer the differentiator. What matters is whether the code reflects judgment, context, and good engineering instincts. AI review can accelerate a lot, but it can also misunderstand why something exists - and that is where professional criteria becomes decisive. Specialization matters: turning one skill into a plugin with three dedicated expert skills was one of the best decisions in the entire project. And evidence beats vibes: if you want to improve a skill seriously, you need evals, comparison, and a repeatable process.&lt;/p&gt;

&lt;p&gt;If you are working with agentic IDEs today, I really think this is the moment to build.&lt;/p&gt;

&lt;p&gt;Create your own skills. Teach them to ask the right questions. Test them with real evals. Compare with and without your guidance. Review them hard. Ship them before you disappear into endless polishing.&lt;/p&gt;

&lt;p&gt;That is how we get better tooling. That is how we stop treating AI assistance like magic and start treating it like engineering.&lt;/p&gt;

&lt;p&gt;And if this plugin helps you do that, even a little, then this journey was worth it.&lt;/p&gt;

&lt;p&gt;If you try it and see ways to improve it, send a PR. I mean that.&lt;/p&gt;

&lt;p&gt;Big hug, Charly&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤖 Your Backlog Speaks, Your IDE listens: How to Build and Test Apps with MCP in Command</title>
      <dc:creator>CharlyAutomatiza</dc:creator>
      <pubDate>Fri, 15 Aug 2025 13:57:42 +0000</pubDate>
      <link>https://dev.to/charlyautomatiza/your-backlog-speaks-your-ide-listens-how-to-build-and-test-apps-with-mcp-in-command-41e8</link>
      <guid>https://dev.to/charlyautomatiza/your-backlog-speaks-your-ide-listens-how-to-build-and-test-apps-with-mcp-in-command-41e8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"This isn't the future, it's the present. The tools are within everyone's reach."&lt;/em&gt; - Buenos Aires Meetup, July 2025&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🎯 The Reality That Changed Everything
&lt;/h2&gt;

&lt;p&gt;Picture this scene: It's 3 PM on a Friday, you have 20 tasks in the backlog, 3 critical bugs, and your PM just arrived with "a small modification" that needs to be ready by Monday. Sound familiar?&lt;/p&gt;

&lt;p&gt;For 19 years in tech, I've lived this reality countless times. But something changed radically in recent months, and no, it's not another JavaScript framework 😄.&lt;/p&gt;

&lt;p&gt;The revolution didn't come from where we expected. It came from being able to &lt;strong&gt;directly converse with our backlog&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚫 The Problem We All Know
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Traditional Development Limitations
&lt;/h3&gt;

&lt;p&gt;In the traditional development cycle, regardless of whether you use Scrum, Kanban, or your preferred methodology, we face the same challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fragmented Communication&lt;/strong&gt;: Between product, UX, development, and QA, there's always "broken telephone"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infinite Manual Processes&lt;/strong&gt;: From idea to code, there are 47 manual steps (I literally counted them once)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gap Between Specification and Result&lt;/strong&gt;: What we ask for vs. what we build vs. what we actually needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: We spend 70% of our time on processes and only 30% solving real problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 The Silent Revolution: MCP Servers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  MCP: My Code's Perfect (Finally!) 🎯
&lt;/h3&gt;

&lt;p&gt;MCP (Model Context Protocol) is the framework that Anthropic launched to solve a problem we all faced: &lt;strong&gt;How do you give specific context to LLMs without going crazy?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each model needed its own implementation&lt;/li&gt;
&lt;li&gt;Your project context was lost&lt;/li&gt;
&lt;li&gt;You had to choose between Claude, GPT, Gemini... and start from scratch each time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One framework, any model&lt;/li&gt;
&lt;li&gt;Your context + LLM power = magic&lt;/li&gt;
&lt;li&gt;Tools that speak directly to your stack&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The "Aha!" Moment
&lt;/h3&gt;

&lt;p&gt;The turning point came when I realized something: &lt;strong&gt;We no longer need to be "10x engineers", we need to be engineers who leverage 10x tools.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ The Experiment: Wallet Sandbox
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setting Up the Laboratory
&lt;/h3&gt;

&lt;p&gt;To demonstrate MCP's power, I created a virtual wallet application with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 15 + App Router&lt;/li&gt;
&lt;li&gt;TypeScript + Tailwind CSS&lt;/li&gt;
&lt;li&gt;Redux Toolkit for state&lt;/li&gt;
&lt;li&gt;Playwright for testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Crucial Part&lt;/strong&gt;: All context was defined in structured documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/BACKLOG.md" rel="noopener noreferrer"&gt;&lt;code&gt;BACKLOG.md&lt;/code&gt;&lt;/a&gt; with detailed user stories&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/BUILD_STANDARDS.md" rel="noopener noreferrer"&gt;&lt;code&gt;BUILD_STANDARDS.md&lt;/code&gt;&lt;/a&gt; with defined processes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/PLAYWRIGHT_STANDARDS.md" rel="noopener noreferrer"&gt;&lt;code&gt;PLAYWRIGHT_STANDARDS.md&lt;/code&gt;&lt;/a&gt; with testing standards&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Protagonists: GitHub MCP and Playwright MCP
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. GitHub MCP: Your AI Project Manager
&lt;/h4&gt;

&lt;p&gt;Available tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete issues and PRs management&lt;/li&gt;
&lt;li&gt;Automatic branch creation&lt;/li&gt;
&lt;li&gt;Reviewer handling&lt;/li&gt;
&lt;li&gt;Project tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Playwright MCP: Your Automated QA
&lt;/h4&gt;

&lt;p&gt;Capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic application exploration&lt;/li&gt;
&lt;li&gt;Context-based test generation&lt;/li&gt;
&lt;li&gt;Intelligent element detection&lt;/li&gt;
&lt;li&gt;Automatic bug reporting&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎬 The Live Show: From Idea to Production
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Act 1: "What Tasks Do I Have Assigned?"
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👤 User: "What tasks do I have assigned in the backlog?"

🤖 AI: [Executes tools automatically]
- ✅ Reads BACKLOG.md
- ✅ Queries GitHub Issues
- ✅ Analyzes open PRs
- ✅ Classifies by priority

Response: "You have 3 pending critical bugs and 1 high-priority US. 
I also detected 2 PRs under review that might need your attention."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔥 Plot Twist&lt;/strong&gt;: I didn't tell it to go to GitHub. I didn't tell it to read the backlog. It simply... did it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act 2: "Implement Scheduled Transfers"
&lt;/h3&gt;

&lt;p&gt;The user story &lt;strong&gt;[US-301]&lt;/strong&gt; was defined in the backlog:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;As&lt;/strong&gt; a wallet user&lt;br&gt;&lt;br&gt;
&lt;strong&gt;I want&lt;/strong&gt; to schedule recurring transfers&lt;br&gt;&lt;br&gt;
&lt;strong&gt;So that&lt;/strong&gt; I can automate periodic payments&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  The Magic of Defined Context
&lt;/h4&gt;

&lt;p&gt;Before executing any code, the system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verified the Mandatory Workflow&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git checkout main
   git pull origin main
   git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/US-301-transferencias-programadas-v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Analyzed Existing Architecture&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js App Router structure&lt;/li&gt;
&lt;li&gt;Established Redux patterns&lt;/li&gt;
&lt;li&gt;Available UI components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Followed Defined Standards&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Naming conventions&lt;/li&gt;
&lt;li&gt;Strict TypeScript&lt;/li&gt;
&lt;li&gt;Server Actions patterns&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Result: 15 Minutes, Complete Functionality
&lt;/h3&gt;

&lt;p&gt;In real-time, during the presentation, it built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Form to schedule transfers&lt;/li&gt;
&lt;li&gt;✅ Frequency selector (one-time, daily, weekly, monthly)&lt;/li&gt;
&lt;li&gt;✅ Future date validations&lt;/li&gt;
&lt;li&gt;✅ Scheduled transfers management page&lt;/li&gt;
&lt;li&gt;✅ Complete integration with existing flow&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Visual Journey: From Concept to Reality
&lt;/h4&gt;

&lt;p&gt;What would traditionally take 2-3 days of development, MCP delivered in just 15 minutes. Here's the actual implementation created during the live presentation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Step 1: Intuitive Transfer Scheduling&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvvczmihhkk1osg2t8ds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvvczmihhkk1osg2t8ds.png" alt="Schedule Transfer Form" width="416" height="922"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;gt; &lt;em&gt;Clean, user-friendly form that guides users through scheduling recurring transfers with frequency options, date validation, and clear input fields - all generated automatically following established design patterns.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Step 2: Immediate Feedback &amp;amp; Confirmation&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmbf65xfyjqg9guu6ysm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmbf65xfyjqg9guu6ysm.png" alt="Transfer Scheduled Successfully" width="424" height="926"&gt;&lt;/a&gt;&lt;br&gt;
&amp;gt; &lt;em&gt;Professional success screen providing users with complete transfer details and clear next steps. The confirmation experience feels polished and trustworthy - exactly what you'd expect from a production app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📊 Step 3: Professional Management Dashboard&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcahrewsao698g99huu4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcahrewsao698g99huu4i.png" alt="Scheduled Transfers Dashboard" width="422" height="920"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;gt; &lt;em&gt;Comprehensive dashboard where users can view, edit, and manage all their scheduled transfers. Each entry shows essential details like amount, frequency, and next execution date, with convenient action buttons for full control.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Traditional vs. MCP Reality:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traditional approach&lt;/strong&gt;: Multiple wireframes, design iterations, component building, state management setup, validation logic, testing cycles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP approach&lt;/strong&gt;: One conversation, instant implementation, production-ready result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Generated code&lt;/strong&gt;: 347 lines across 5 files&lt;br&gt;
&lt;strong&gt;Traditional development time estimate&lt;/strong&gt;: 2-3 days&lt;br&gt;
&lt;strong&gt;Real time with MCP&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;h3&gt;
  
  
  Act 3: Automatic Testing with Playwright MCP
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👤 User: "What tests do you suggest I perform?"

🤖 AI with Playwright MCP:
- ✅ Analyzes built functionality
- ✅ Identifies critical flows
- ✅ Generates and executes tests automatically
- ✅ Detects console errors
- ✅ Validates behavior across different browsers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The Surprising Part&lt;/strong&gt;: It found bugs we didn't even know existed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Note&lt;/strong&gt;: During the demo, I had to manage the tool limit in VS Code, strategically switching between GitHub MCP and Playwright MCP to optimize performance for different development phases.&lt;/p&gt;
&lt;h3&gt;
  
  
  Act 4: The Virtuous Circle
&lt;/h3&gt;

&lt;p&gt;When Playwright MCP detected minor console errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👤 User: "Create a bug ticket with the detected error"

🤖 GitHub MCP:
- ✅ Analyzes the found error
- ✅ Gathers context and evidence
- ✅ Creates structured issue in GitHub
- ✅ Assigns appropriate labels and severity
- ✅ Includes reproduction steps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Complete issue with all necessary information, ready to be worked on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act 5: Complete Automation Cycle - The Live Demo Finale
&lt;/h3&gt;

&lt;p&gt;This is where the audience witnessed something unprecedented. After being satisfied with the implementation, I demonstrated the complete automated publication cycle:&lt;/p&gt;

&lt;h4&gt;
  
  
  The Automated Publication Process
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👤 User: "I'm satisfied with the implementation. Let's publish this."

🤖 GitHub MCP (following predefined rules):
- ✅ Validates all code changes
- ✅ Executes automatic commit with proper message format
- ✅ Pushes branch to remote repository
- ✅ Creates pull request with detailed description
- ✅ Assigns configured reviewers automatically
- ✅ Links PR to original user story issue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What the audience saw&lt;/strong&gt;: A complete Git workflow executed through natural language commands, all because the rules were predefined in the Copilot instructions.&lt;/p&gt;

&lt;h4&gt;
  
  
  The AI-Powered Code Review Cycle
&lt;/h4&gt;

&lt;p&gt;Within minutes of the PR creation, the real magic happened:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🤖 GitHub Copilot (automatically):
- ✅ Reviews the generated code
- ✅ Analyzes implementation patterns
- ✅ Posts detailed review comments with suggestions
- ✅ Identifies potential improvements
- ✅ Suggests best practices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Accessing Review Feedback
&lt;/h4&gt;

&lt;p&gt;During the demo, I showed how to interact with the review process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👤 User: "Analyze all the comments on my PR"

🤖 GitHub MCP:
- ✅ Retrieves all review comments automatically
- ✅ Analyzes and summarizes feedback and suggestions
- ✅ Categorizes comments by importance
- ✅ Provides context for each suggestion
- ✅ Suggests possible action plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real review comments analyzed included&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Direct state mutation issues&lt;/li&gt;
&lt;li&gt;Navigation in render problems&lt;/li&gt;
&lt;li&gt;Hook usage improvements&lt;/li&gt;
&lt;li&gt;Performance optimization opportunities&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Complete Cycle Metrics
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Real demo timeline&lt;/strong&gt; (~20 minutes total):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature implementation: 15 minutes&lt;/li&gt;
&lt;li&gt;Automated testing: 2 minutes&lt;/li&gt;
&lt;li&gt;Publication workflow: 1 minute&lt;/li&gt;
&lt;li&gt;Copilot review: Automatic (2 minutes)&lt;/li&gt;
&lt;li&gt;Issue creation: 30 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Traditional workflow estimate&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature implementation: 2-3 days&lt;/li&gt;
&lt;li&gt;Testing and debugging: 4-6 hours&lt;/li&gt;
&lt;li&gt;Code review process: 1-2 days&lt;/li&gt;
&lt;li&gt;Bug reporting and tracking: 1-2 hours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total&lt;/strong&gt;: 4-6 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Productivity improvement&lt;/strong&gt;: ~96% time reduction&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 The Ingredients for Success
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Copilot Instructions (The Project's DNA)
&lt;/h3&gt;

&lt;p&gt;The secret lies in the instructions you define. My instructions file included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;⚠️ &lt;span class="gs"&gt;**CRITICAL WORKFLOW REQUIREMENT**&lt;/span&gt; ⚠️
ALWAYS START by verifying backlog task and Git workflow steps BEFORE suggesting any technical solution.
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**Enhanced Task Discovery Process**&lt;/span&gt;:
&lt;span class="p"&gt;   -&lt;/span&gt; Read BACKLOG.md first
&lt;span class="p"&gt;   -&lt;/span&gt; Search GitHub Issues if task not found
&lt;span class="p"&gt;   -&lt;/span&gt; Confirm task ID (US-XXX, TT-XXX, BG-XXX)
&lt;span class="p"&gt;
2.&lt;/span&gt; &lt;span class="gs"&gt;**Git Workflow**&lt;/span&gt;:
&lt;span class="p"&gt;   -&lt;/span&gt; Start from updated main
&lt;span class="p"&gt;   -&lt;/span&gt; Create feature branch following naming convention
&lt;span class="p"&gt;   -&lt;/span&gt; Follow commit message standards
&lt;span class="p"&gt;
3.&lt;/span&gt; &lt;span class="gs"&gt;**Development Standards**&lt;/span&gt;:
&lt;span class="p"&gt;   -&lt;/span&gt; Next.js 15 with App Router
&lt;span class="p"&gt;   -&lt;/span&gt; TypeScript strict mode
&lt;span class="p"&gt;   -&lt;/span&gt; Component structure patterns
&lt;span class="p"&gt;
4.&lt;/span&gt; &lt;span class="gs"&gt;**Publication Rules**&lt;/span&gt;:
&lt;span class="p"&gt;   -&lt;/span&gt; Auto-commit with proper message format
&lt;span class="p"&gt;   -&lt;/span&gt; Auto-push to remote branch
&lt;span class="p"&gt;   -&lt;/span&gt; Auto-create PR with detailed description
&lt;span class="p"&gt;   -&lt;/span&gt; Auto-assign reviewers including Copilot
&lt;span class="p"&gt;   -&lt;/span&gt; Auto-apply labels and issue linking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Structured Documentation
&lt;/h3&gt;

&lt;p&gt;Every aspect of the project was documented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BACKLOG.md&lt;/strong&gt;: 50+ user stories with acceptance criteria&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BUILD_STANDARDS.md&lt;/strong&gt;: Development processes and Git workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PLAYWRIGHT_STANDARDS.md&lt;/strong&gt;: Testing standards and Page Object Model&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Context, Not Commands
&lt;/h3&gt;

&lt;p&gt;Instead of saying "do X", I defined &lt;strong&gt;why&lt;/strong&gt; and &lt;strong&gt;how&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Test Automation Standards&lt;/span&gt;

&lt;span class="gu"&gt;### Pre-Publication Validation&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; ALWAYS validate tests execute successfully before publishing changes
&lt;span class="p"&gt;-&lt;/span&gt; Distinguish between test failures and application bugs
&lt;span class="p"&gt;-&lt;/span&gt; Create GitHub Issues for application defects with comprehensive evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Technical Constraints and Solutions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Tool Limitations&lt;/strong&gt;: VS Code has a tool limit for MCP servers, requiring strategic tool selection during different phases of development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context Management&lt;/strong&gt;: Longer conversations can impact performance, sometimes requiring fresh contexts for complex workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 The Numbers That Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before vs. After
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;Traditional Method&lt;/th&gt;
&lt;th&gt;With MCP&lt;/th&gt;
&lt;th&gt;Reduction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Backlog analysis&lt;/td&gt;
&lt;td&gt;30 min&lt;/td&gt;
&lt;td&gt;2 min&lt;/td&gt;
&lt;td&gt;93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature implementation&lt;/td&gt;
&lt;td&gt;2-3 days&lt;/td&gt;
&lt;td&gt;15 min&lt;/td&gt;
&lt;td&gt;99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test creation&lt;/td&gt;
&lt;td&gt;4-6 hours&lt;/td&gt;
&lt;td&gt;2 min&lt;/td&gt;
&lt;td&gt;99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bug reporting&lt;/td&gt;
&lt;td&gt;20 min&lt;/td&gt;
&lt;td&gt;30 seconds&lt;/td&gt;
&lt;td&gt;97%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code review setup&lt;/td&gt;
&lt;td&gt;5 min&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complete cycle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4-6 days&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~20 min&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~96%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Output Quality
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standards adherence&lt;/strong&gt;: Consistent (predefined rules)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatically detected bugs&lt;/strong&gt;: Comprehensive test coverage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generated documentation&lt;/strong&gt;: Complete and up-to-date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review coverage&lt;/strong&gt;: Automatic and thorough&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Practical Implementation: Your Roadmap
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: Preparation (1 week)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Document Your Context&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - Create BACKLOG.md with your current tasks
   - Define BUILD_STANDARDS.md with your processes
   - Structure TESTING_STANDARDS.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Your IDE&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VS Code with native MCP support&lt;/li&gt;
&lt;li&gt;Or Cursor with cursor rules&lt;/li&gt;
&lt;li&gt;Install necessary MCP Servers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Define Your Copilot Instructions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git workflows&lt;/li&gt;
&lt;li&gt;Code standards&lt;/li&gt;
&lt;li&gt;Testing processes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Publication automation rules&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Phase 2: First Experiments (1 week)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Simple&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   "What pending tasks do I have in my backlog?"
   "Analyze this code and suggest improvements"
   "Create a test for this functionality"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Iterate the Instructions&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Observe what works and what doesn't&lt;/li&gt;
&lt;li&gt;Adjust context based on results&lt;/li&gt;
&lt;li&gt;Refine standards&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Phase 3: Complete Integration (2 weeks)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Complete Workflows&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Backlog → Implementation → Testing → PR → Deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Automation&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Automatic bug detection&lt;/li&gt;
&lt;li&gt;Performance testing&lt;/li&gt;
&lt;li&gt;Documentation generation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automated code review cycles&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Recommended Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  IDEs with MCP Support
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VS Code&lt;/strong&gt;: Native support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor&lt;/strong&gt;: Excellent integration, no tool limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Desktop&lt;/strong&gt;: For quick experimentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Essential MCP Servers
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub MCP&lt;/strong&gt;: Project and code management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playwright MCP&lt;/strong&gt;: Automated testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase MCP&lt;/strong&gt;: Database and backend services - &lt;a href="https://supabase.com/docs/guides/getting-started/mcp" rel="noopener noreferrer"&gt;Getting Started&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Your Next Move: The Revolution Starts Now
&lt;/h2&gt;

&lt;h3&gt;
  
  
  For Developers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The competitive advantage is real, and the window is open now.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;This Week&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download VS Code or Cursor&lt;/li&gt;
&lt;li&gt;Configure GitHub MCP&lt;/li&gt;
&lt;li&gt;Have your first conversation with the backlog&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;This Month&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement your first complete feature with MCP&lt;/li&gt;
&lt;li&gt;Automate your testing suite&lt;/li&gt;
&lt;li&gt;Measure the time saved&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Set up automated publication workflows&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;This Quarter&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make MCP your main workflow&lt;/li&gt;
&lt;li&gt;Train your team&lt;/li&gt;
&lt;li&gt;Document your processes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Become the productivity multiplier for your organization&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  For Product Managers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;It's time to get closer to technical implementation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP democratizes development. Now you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Converse directly with the backlog&lt;/li&gt;
&lt;li&gt;Validate implementations in real-time&lt;/li&gt;
&lt;li&gt;Iterate ideas without waiting for complete sprints&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;See changes in production within hours, not weeks&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  For CTOs and Tech Leads
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The competitive advantage lies in early adoption.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that adopt MCP now will have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Significantly faster development cycles&lt;/li&gt;
&lt;li&gt;Consistent quality through predefined standards&lt;/li&gt;
&lt;li&gt;Lower learning curve for new developers&lt;/li&gt;
&lt;li&gt;Documentation that stays current automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Complete traceability from idea to production&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🌟 Final Reflections
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The New Reality
&lt;/h3&gt;

&lt;p&gt;After 19 years in technology, I can affirm that &lt;strong&gt;we've never been so close to democratizing software development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;MCP doesn't replace technical knowledge, it amplifies it. You still need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand the problem you're solving&lt;/li&gt;
&lt;li&gt;Know the technologies you use&lt;/li&gt;
&lt;li&gt;Define clear processes and standards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But now, instead of spending time on repetitive tasks, you can &lt;strong&gt;converse with your backlog and build solutions&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Live Demo Impact
&lt;/h3&gt;

&lt;p&gt;During the Buenos Aires Meetup, someone asked: &lt;em&gt;"How do you see the future of these tools?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My answer was clear: &lt;strong&gt;Let's not talk about the future. Let's talk about the present.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The tools are here. MCP Servers are available. IDEs have native support.&lt;/p&gt;

&lt;p&gt;What we demonstrated live wasn't a vision—it was reality. &lt;strong&gt;In 20 minutes, we went from user story to production-ready code with automated testing, code review, and bug tracking.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The only question left is: &lt;strong&gt;When are you going to start?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 Resources and Links
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox" rel="noopener noreferrer"&gt;Wallet Sandbox - Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/.github/copilot-instructions.md" rel="noopener noreferrer"&gt;Copilot Instructions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro" rel="noopener noreferrer"&gt;MCP Getting Started Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox" rel="noopener noreferrer"&gt;Project Documentation&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/BACKLOG.md" rel="noopener noreferrer"&gt;BACKLOG.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/BUILD_STANDARDS.md" rel="noopener noreferrer"&gt;BUILD_STANDARDS.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/PLAYWRIGHT_STANDARDS.md" rel="noopener noreferrer"&gt;PLAYWRIGHT_STANDARDS.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/charlyautomatiza/wallet-sandbox/blob/main/.cursorrules" rel="noopener noreferrer"&gt;.cursorrules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Official MCP Servers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/github" rel="noopener noreferrer"&gt;GitHub MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/playwright" rel="noopener noreferrer"&gt;Playwright MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/modelcontextprotocol/servers" rel="noopener noreferrer"&gt;MCP Servers Directory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Connect With Me
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;a href="https://charlyautomatiza.tech" rel="noopener noreferrer"&gt;charlyautomatiza.tech&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;𝕏 &lt;a href="https://twitter.com/char_automatiza" rel="noopener noreferrer"&gt;@char_automatiza&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 &lt;a href="https://linkedin.com/in/gautocarlos" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📺 &lt;a href="https://youtube.com/charlyautomatiza" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Presentation Video
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎥 &lt;a href="https://www.youtube.com/watch?v=AuDmzxDg3oA" rel="noopener noreferrer"&gt;Buenos Aires Meetup - July 2025&lt;/a&gt; &lt;em&gt;(Video in Spanish)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Was this article useful to you? Share it with your team and let's start the MCP revolution together. Your backlog is waiting for you to talk to it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The revolution has begun. The only question is: Are you part of it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#MCP #Development #Automation #AI #Productivity #GitHub #Playwright #VSCode&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Grafana K6 cheat sheet: everything a performance engineer should know</title>
      <dc:creator>CharlyAutomatiza</dc:creator>
      <pubDate>Fri, 25 Oct 2024 01:48:35 +0000</pubDate>
      <link>https://dev.to/charlyautomatiza/grafana-k6-cheat-sheet-everything-a-performance-engineer-should-know-49od</link>
      <guid>https://dev.to/charlyautomatiza/grafana-k6-cheat-sheet-everything-a-performance-engineer-should-know-49od</guid>
      <description>&lt;h2&gt;
  
  
  Grafana K6 Cheat Sheet: Everything a Performance Engineer Should Know (with Examples and Best Practices)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Introduction to Grafana K6
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://grafana.com/docs/k6/latest/" rel="noopener noreferrer"&gt;Grafana K6&lt;/a&gt; is an open-source tool designed for performance testing. It's great for testing APIs, microservices, and websites at scale, providing developers and testers insights into system performance. This cheat sheet will cover the key aspects every performance engineer should know to get started with Grafana K6.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Grafana K6?
&lt;/h4&gt;

&lt;p&gt;Grafana K6 is a modern load testing tool for developers and testers that makes performance testing simple, scalable, and easy to integrate into your CI pipeline.&lt;/p&gt;

&lt;h4&gt;
  
  
  When to use it?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Load testing&lt;/li&gt;
&lt;li&gt;Stress testing&lt;/li&gt;
&lt;li&gt;Spike testing&lt;/li&gt;
&lt;li&gt;Performance bottleneck detection&lt;/li&gt;
&lt;li&gt;API testing&lt;/li&gt;
&lt;li&gt;Browser testing&lt;/li&gt;
&lt;li&gt;Chaos engineering&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Grafana K6 Cheat Sheet: Essential Aspects
&lt;/h3&gt;

&lt;h4&gt;
  
  
  2.1. Installation
&lt;/h4&gt;

&lt;p&gt;Install Grafana K6 via Homebrew or Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;k6
&lt;span class="c"&gt;# Or with Docker&lt;/span&gt;
docker run &lt;span class="nt"&gt;-i&lt;/span&gt; grafana/k6 run - &amp;lt;script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2.2. Basic Test with a Public REST API
&lt;/h4&gt;

&lt;p&gt;Here's how to run a simple test using a public REST API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6/http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define the API endpoint and expected response&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://jsonplaceholder.typicode.com/posts/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Define the expected response&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sunt aut facere repellat provident occaecati excepturi optio reprehenderit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quia et suscipit&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;suscipit recusandae consequuntur expedita et cum&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;reprehenderit molestiae ut ut quas totam&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;nostrum rerum est autem sunt rem eveniet architecto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Assert the response is as expected&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response is correct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedResponse&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2.2.1 Running the test and utilization of web dashboard
&lt;/h5&gt;

&lt;p&gt;To run the test and view the results in a web dashboard, we can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;K6_WEB_DASHBOARD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true &lt;/span&gt;&lt;span class="nv"&gt;K6_WEB_DASHBOARD_EXPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;html-report.html k6 run ./src/rest/jsonplaceholder-api-rest.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a report in the reports folder with the name html-report.html.&lt;/p&gt;

&lt;p&gt;But we also can see the results in the web dashboard by accessing the following URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:5665/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgu3ufo8fweo3dj3k62zp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgu3ufo8fweo3dj3k62zp.png" alt="k6-web-dashboard-access" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we access the URL, we can see the results on real time of the test in the web dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkykbndbqw7ewjfmgiv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkykbndbqw7ewjfmgiv1.png" alt="k6-web-dashboard" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2.3. Test with a Public GraphQL API
&lt;/h4&gt;

&lt;p&gt;Example using a public GraphQL API.&lt;/p&gt;

&lt;p&gt;If you don't know what is a GraphQL API, you can visit the following URL: &lt;a href="https://graphql.org/learn/" rel="noopener noreferrer"&gt;What is GraphQL?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more information about the GraphQL API we are going to use, you can visit the documentation of the following URL: &lt;a href="https://graphql-pokemon2.vercel.app/" rel="noopener noreferrer"&gt;GraphQL Pokémon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more information about how to test GraphQL APIs, you can visit the following URL: &lt;a href="https://katalon.com/resources-center/blog/graphql-testing" rel="noopener noreferrer"&gt;GraphQL Testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a simple test to get a pokemon by name and check if the response is successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6/http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define the query and variables&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  query getPokemon($name: String!) {
    pokemon(name: $name) {
      id
      name
      types
    }
  }`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pikachu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Define the test function&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://graphql-pokemon2.vercel.app/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Define the headers&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Make the request&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Define the expected response&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UG9rZW1vbjowMjU=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pikachu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Electric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Assert the response is as expected&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response is correct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedResponse&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Best Practices for Structuring Performance Projects
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3.1. Centralized Configuration
&lt;/h4&gt;

&lt;p&gt;Define global configurations &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/config/options.js" rel="noopener noreferrer"&gt;options&lt;/a&gt; such as performance thresholds, the number of virtual users (VU), and durations in one place for easy modification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/config/options.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// ramp up to 100 VUs&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// stay at 100 VUs for 5 mins&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;   &lt;span class="c1"&gt;// ramp down&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;thresholds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;http_req_duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p(95)&amp;lt;500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// 95% of requests should complete in under 500ms&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.2. Code Modularity
&lt;/h4&gt;

&lt;h4&gt;
  
  
  3.2.1. Constants and Requests for the REST API
&lt;/h4&gt;

&lt;p&gt;Separate code into reusable modules, for example, separating constants and requests from test logic.&lt;/p&gt;

&lt;p&gt;For our REST API example, we can create a &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/constants.js" rel="noopener noreferrer"&gt;constants.js&lt;/a&gt; file to store the base URL of the API and a &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/requests-jsonplaceholder.js" rel="noopener noreferrer"&gt;requests-jsonplaceholder.js&lt;/a&gt; file to store the functions to interact with the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/utils/constants.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can create the &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/requests-jsonplaceholder.js" rel="noopener noreferrer"&gt;requests-jsonplaceholder.js&lt;/a&gt; file to store the functions to interact with the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/utils/requests-jsonplaceholder.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BASE_URLS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./constants.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;k6/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.2.2. Integration of Requests in the Test Script of the REST API
&lt;/h4&gt;

&lt;p&gt;Finally, we can create our test script &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/rest/jsonplaceholder-api-rest.js" rel="noopener noreferrer"&gt;jsonplaceholder-api-rest.js&lt;/a&gt; to use the functions we created in the &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/requests-jsonplaceholder.js" rel="noopener noreferrer"&gt;requests-jsonplaceholder.js&lt;/a&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/rest/jsonplaceholder-api-rest.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatePost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deletePost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../utils/requests-jsonplaceholder.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../config/options.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// GET request&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET response has correct id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// POST request&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST status is 201&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST response has id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// PUT request&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sunt aut facere repellat provident occaecati excepturi optio reprehenderit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quia et suscipit&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;suscipit recusandae consequuntur expedita et cum&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;reprehenderit molestiae ut ut quas totam&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;nostrum rerum est autem sunt rem eveniet architecto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;updatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatedPost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT response has updated title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo updated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// DELETE request&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DELETE status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our script code is now much simpler to understand, and if something changes in the URL, parameters or if a new method needs to be added, the place where the changes need to be made is centralised, making our solution simpler to extend over time.&lt;/p&gt;

&lt;p&gt;We could further improve our scripts by creating more atomic functions that we can reuse to create more complex scenarios in the future if necessary, it is getting simpler to understand what our test script does. For example if we wanted to test the existence of a post, we could create a function that gets a post and returns the response, then we could use this function in our test script &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/rest/jsonplaceholder-api-rest.js" rel="noopener noreferrer"&gt;jsonplaceholder-api-rest.js&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/rest/jsonplaceholder-api-rest.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatePost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deletePost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../utils/requests-jsonplaceholder.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../config/options.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Function to test GET request&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testGetPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET response has correct id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function to test POST request&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testCreatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST status is 201&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST response has id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function to test PUT request&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testUpdatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;updatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT response has updated title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function to test DELETE request&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testDeletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DELETE status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Main function&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;testGetPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nf"&gt;testCreatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sunt aut facere repellat provident occaecati excepturi optio reprehenderit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quia et suscipit&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;suscipit recusandae consequuntur expedita et cum&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;reprehenderit molestiae ut ut quas totam&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;nostrum rerum est autem sunt rem eveniet architecto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nf"&gt;testUpdatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatedPost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;testDeletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.2.3. Constants and Requests for the GraphQL API
&lt;/h4&gt;

&lt;p&gt;We can modify the &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/constants.js" rel="noopener noreferrer"&gt;constants.js&lt;/a&gt; file to add the base URL of the GraphQL API and the headers we need to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/utils/constants.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;REST_API&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;GRAPHQL_POKEMON&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://graphql-pokemon2.vercel.app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can create the &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/requests-graphql-pokemon.js" rel="noopener noreferrer"&gt;requests-graphql-pokemon.js&lt;/a&gt; file to store the functions to interact with the GraphQL API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/utils/requests-graphql-pokemon.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HEADERS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./constants.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6/http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Get a pokemon by name and return the fields specified in the fields array&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fieldsString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    query getPokemon($name: String!) {
      pokemon(name: $name) {
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fieldsString&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      }
    }
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pokemonVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pokemonVariables&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BASE_URLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GRAPHQL_POKEMON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HEADERS&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.2.4. Integration of Requests in the Test Script of the GraphQL API
&lt;/h4&gt;

&lt;p&gt;In this moment we can create our test script to use the functions we created in the &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/utils/requests-graphql-pokemon.js" rel="noopener noreferrer"&gt;requests-graphql-pokemon.js&lt;/a&gt; file. We will create a simple test script that will get the data of a pokemon and check if the response is successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/pokemon-graphql-test.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPokemon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../utils/requests-graphql-pokemon.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define the test function&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pikachu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Define the expected response&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UG9rZW1vbjowMjU=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pikachu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Electric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Assert the response is as expected&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response is correct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedResponse&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the same way as for the example of api rest, we can improve our script by creating more atomic functions that we can reuse to create more complex scenarios in the future if necessary, it is getting simpler to understand what our test script does.&lt;/p&gt;

&lt;p&gt;There is still a better way to optimise and have a better parameterisation of the response and request results, what do you imagine we could do?&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3. Dynamic Data and Parameterization
&lt;/h4&gt;

&lt;p&gt;Use dynamic data to simulate more realistic scenarios and load different data sets. K6 allows us to use shared arrays to load data from a file. Shared arrays are a way to store data that can be accessed by all VUs.&lt;/p&gt;

&lt;p&gt;We can create a &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/config/users-config.js" rel="noopener noreferrer"&gt;users-config.js&lt;/a&gt; file to load the users data from a JSON file &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/data/users.json" rel="noopener noreferrer"&gt;users.json&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/config/users-config.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SharedArray&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;k6/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SharedArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../data/users.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Load from a file&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we can use it in our test script &lt;a href="https://github.com/charlyautomatiza/k6-cheat-sheet/blob/main/src/rest/jsonplaceholder-api-rest.js" rel="noopener noreferrer"&gt;jsonplaceholder-api-rest.js&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/rest/jsonplaceholder-api-rest.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../utils/requests-jsonplaceholder.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../config/options.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../config/users-config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Function to test GET request&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testGetPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET response has correct id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Main function&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;

  &lt;span class="nf"&gt;testGetPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Project Structure
&lt;/h3&gt;

&lt;p&gt;A well-organized project structure helps in maintaining and scaling your tests. Here's a suggested folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/project-root
│
├── /src
│   ├── /graphql
│   │   ├── pokemon-graphql-test.js      # Test for GraphQL Pokémon API
│   │   ├── other-graphql-test.js        # Other GraphQL tests
│   │
│   ├── /rest
│   │   ├── jsonplaceholder-api-rest.js # REST API test for JSONPlaceholder
│   │   ├── other-rest-test.js          # Another REST API test
│   │
│   └── performance-scenarios.js  # Script combining multiple performance tests
│
├── /utils
│   ├── requests-graphql-pokemon.js # Reusable functions for GraphQL requests
│   ├── requests-jsonplaceholder.js # Reusable functions for REST requests
│   ├── checks.js                   # Reusable validation functions
│   ├── constants.js             # Global constants, like URLs or headers
│
├── /config
│   ├── options.js                # Global configuration options
│   ├── users-config.js           # Configuration for users data
│
├── /reports
│   └── results.html             # Output file for results (generated after running tests)
│
├── /data
│   └── users.json             # Users data
│
├── README.md                    # Project documentation
└── .gitignore                   # Files and folders ignored by Git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure helps in keeping your project organized, scalable, and easy to maintain, avoiding clutter in the project root.&lt;/p&gt;

&lt;p&gt;Another option would be to group test scripts into folders by functionality, you can test and compare what makes the most sense for your context. For example, if your project about a wallet that makes transactions, you could have a folder for each type of transaction (deposit, withdrawal, transfer, etc.) and inside each folder you could have the test scripts for that specific transaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/project-root
│
├── /src
│   ├── /deposit
│   │   ├── deposit-test-1.js      # Test for deposit
│   │   ├── deposit-test-2.js      # Another deposit test
│   │
│   ├── /withdrawal
│   │   ├── withdrawal-test-1.js      # Test for withdrawal
│   │   ├── withdrawal-test-2.js      # Another withdrawal test
│   │
│   ├── /transfer
│   │   ├── transfer-test-1.js      # Test for transfer
│   │   ├── transfer-test-2.js      # Another transfer test
│   │
│   └── performance-scenarios.js  # Script combining multiple performance tests
│
├── /utils
│   ├── requests-deposit.js # Reusable functions for deposit
│   ├── requests-withdrawal.js # Reusable functions for withdrawal
│   ├── requests-transfer.js # Reusable functions for transfer
│   ├── checks.js             # Reusable validation functions
│   ├── constants.js          # Global constants, like URLs or headers
│
├── /config
│   ├── options.js                # Global configuration options
│   ├── users-config.js           # Configuration for users data
│   ├── accounts-config.js        # Configuration for accounts data
│
├── /reports
│   └── results.html             # Output file for results (generated after running tests)
│
├── /data
│   └── users.json             # Users data
│   └── accounts.json          # Accounts data
│
├── README.md                    # Project documentation
└── .gitignore                   # Files and folders ignored by Git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On this second example, we have a more complex data structure, but we can still reuse the same requests functions that we created for the first example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Performance testing with K6 is critical for identifying bottlenecks and ensuring application scalability. By following best practices such as modularizing code, centralizing configurations, and using dynamic data, engineers can create maintainable and scalable performance testing scripts.&lt;/p&gt;

&lt;p&gt;Big hug.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Charly Automatiza&lt;/code&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>k6</category>
      <category>grafana</category>
      <category>performance</category>
    </item>
    <item>
      <title>Book review: Enhanced Test Automation with WebdriverIO: Unlock the superpowers of hybrid testing framework</title>
      <dc:creator>CharlyAutomatiza</dc:creator>
      <pubDate>Fri, 26 Jan 2024 16:55:59 +0000</pubDate>
      <link>https://dev.to/charlyautomatiza/book-review-enhanced-test-automation-with-webdriverio-unlock-the-superpowers-of-hybrid-testing-framework-26bk</link>
      <guid>https://dev.to/charlyautomatiza/book-review-enhanced-test-automation-with-webdriverio-unlock-the-superpowers-of-hybrid-testing-framework-26bk</guid>
      <description>&lt;h2&gt;
  
  
  My motivation
&lt;/h2&gt;

&lt;p&gt;This year I set myself the personal goal of reading at least one book a month that is not in my native language. In this case, I also have the goal of reading in English, but also to start reading books in Portuguese, as I am slowly learning this language.&lt;/p&gt;

&lt;p&gt;Having said that, I am going to give you my personal opinion about this book.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the book
&lt;/h2&gt;

&lt;p&gt;In my opinion, &lt;a href="https://github.com/webdriverio/webdriverio" rel="noopener noreferrer"&gt;WebDriverIO&lt;/a&gt; (Next-gen browser and mobile automation test framework for &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;) is one of the most complete and versatile modern frameworks.&lt;br&gt;
Just by seeing the wide variety of topics that were going to be covered just by reading the table of contents, I already had very &lt;strong&gt;high expectations&lt;/strong&gt; and &lt;strong&gt;honestly it exceeded them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are someone who is just starting out in the field of &lt;strong&gt;Test Automation&lt;/strong&gt;, you will be able to see the basics little by little, although if you are an experienced SDET, you will see more than one tip in the first few pages that you certainly didn't know about.&lt;/p&gt;

&lt;p&gt;We are gradually getting into more and more &lt;strong&gt;complex topics&lt;/strong&gt; in a progressive and very enjoyable way. Something that I found very successful is that from &lt;strong&gt;the 3rd chapter&lt;/strong&gt; we are taught how to &lt;strong&gt;debug&lt;/strong&gt; our tests, remember that &lt;strong&gt;test automation is part of software development&lt;/strong&gt; and as in any construction cycle, debugging errors is a fundamental part.&lt;/p&gt;

&lt;p&gt;Complex topics such as callbacks, promises and async/await in &lt;strong&gt;JavaScript/TypeScript&lt;/strong&gt; are addressed in a practical and simple way, the unfamiliar reader will quickly understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapters 5 to 8&lt;/strong&gt; dives right into the implementation of helpers, I really enjoyed this, showing these implementations to those who are just starting out is a great accelerator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapter 9&lt;/strong&gt; will explain all about &lt;strong&gt;Page Object Model&lt;/strong&gt; A.k.A &lt;strong&gt;POM&lt;/strong&gt;, one of the most used design patterns in test automation, you will also see an alternative to implement POM/BDD using &lt;a href="https://github.com/klassijs/klassi-js" rel="noopener noreferrer"&gt;Klassi-js&lt;/a&gt;, a framework that I didn't know and that has several very interesting features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapters 10 and 12&lt;/strong&gt; seem to me key chapters as they explain how to write robust selectors, I found a great success to show all the potential that the editor of selectors &lt;a href="https://www.selectorshub.com" rel="noopener noreferrer"&gt;SelectorsHub&lt;/a&gt; gives us to once again, simplify our task and minimize future maintenance.&lt;/p&gt;

&lt;p&gt;The authors also present &lt;strong&gt;very creative solutions&lt;/strong&gt; to make our selectors &lt;strong&gt;"self-healing"&lt;/strong&gt; and very &lt;strong&gt;tolerant to changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional note&lt;/strong&gt;: It is always a good time to recommend the use of this tool, not because I am an &lt;a href="https://selectorshub.com/ambassador-program" rel="noopener noreferrer"&gt;SelectorsHub Ambassador&lt;/a&gt;, as I have always recommended this tool long before, which I consider a great time saver.&lt;/p&gt;

&lt;p&gt;In the last chapters we will see how to integrate our solution to &lt;a href="https://allurereport.org/" rel="noopener noreferrer"&gt;Allure Report&lt;/a&gt;, in my opinion one of the best Automation Test Reporting tool, and also how to run our tests in a scalable way in multiple browsers both in locally mounted environments using Selenium Grid and also using the powerful cloud solution such as &lt;a href="https://lambdatest.com" rel="noopener noreferrer"&gt;LambaTest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To close and complement the basic circuit of automation, we will see and learn how to use &lt;a href="https://www.jenkins.io" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;, one of the most used tools for &lt;strong&gt;continuous integration&lt;/strong&gt;, do not worry if it is your first time with &lt;strong&gt;Jenkins&lt;/strong&gt;, the authors will accompany you to learn how to install and even show you how to have constant feedback through the integration of &lt;a href="https://allurereport.org/" rel="noopener noreferrer"&gt;Allure Reports&lt;/a&gt; and also with &lt;a href="https://slack.com" rel="noopener noreferrer"&gt;Slack&lt;/a&gt; messages.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;appendix&lt;/strong&gt; is super rich, reading it reminded me of the times I had those errors that are described there and the time I had to invest to be able to give solution, will be your almost constant consultation section to each error and surely you will find the solution and &lt;strong&gt;save a lot of time&lt;/strong&gt;, I assure you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I must say that I really enjoyed reading &lt;a href="https://www.amazon.com/Enhanced-Test-Automation-WebdriverIO-superpowers/dp/1837630186" rel="noopener noreferrer"&gt;Enhanced Test Automation with WebdriverIO: Unlock the superpowers of hybrid testing frameworks&lt;/a&gt;, I felt identified having implemented, &lt;strong&gt;in real projects&lt;/strong&gt;, similar solutions to those exposed by the authors and I also took a lot of knowledge that I did not have before.&lt;/p&gt;

&lt;p&gt;It is recommended both for &lt;strong&gt;beginners&lt;/strong&gt; and for those who may have &lt;strong&gt;extensive experience&lt;/strong&gt; with test automation, shows the full potential of &lt;strong&gt;WebDriverIO&lt;/strong&gt; profiling it on par with the most robust modern frameworks of today and prepares the ground to implement robust solutions &lt;strong&gt;from zero to CI/CD&lt;/strong&gt;, building &lt;strong&gt;solid selectors&lt;/strong&gt; and using &lt;strong&gt;cloud solutions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Many thanks to the authors &lt;a href="https://www.linkedin.com/in/pmgrossman/" rel="noopener noreferrer"&gt;Paul M. Grossman&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/larryg/" rel="noopener noreferrer"&gt;Larry C. Goddard&lt;/a&gt; for delivering a great work.&lt;/p&gt;

&lt;p&gt;I also want to thank &lt;a href="https://www.linkedin.com/in/shrinidhi-m-v-356159184/" rel="noopener noreferrer"&gt;Shrinidh&lt;/a&gt; and &lt;a href="https://www.packtpub.com/" rel="noopener noreferrer"&gt;Packt&lt;/a&gt; for sending me this book, I have learned a lot.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Charly&lt;/code&gt;&lt;/p&gt;

</description>
      <category>webdriverio</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
