<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <p>Testing documentation for Geode covers unit testing, integration testing, performance benchmarking, and quality assurance practices. Learn how to test applications built on Geode, validate queries, and ensure production readiness with comprehensive test coverage.</p> <h3 id="testing-philosophy" class="position-relative d-flex align-items-center group"> <span>Testing Philosophy</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing-philosophy" aria-haspopup="dialog" aria-label="Share link: Testing Philosophy"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Geode achieves 97.4% test coverage (1,644/1,688 tests passing) through rigorous testing at multiple levels. The project follows evidence-based development with CANARY governance markers linking requirements to test evidence, ensuring every feature is properly validated.</p> <h3 id="unit-testing" class="position-relative d-flex align-items-center group"> <span>Unit Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="unit-testing" aria-haspopup="dialog" aria-label="Share link: Unit Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="testing-geode-applications" class="position-relative d-flex align-items-center group"> <span>Testing Geode Applications</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing-geode-applications" aria-haspopup="dialog" aria-label="Share link: Testing Geode Applications"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Python application tests</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pytest</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">geode_client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.fixture</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">client</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Shared Geode client for tests.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">client</span> <span class="o">=</span> <span class="n">geode_client</span><span class="o">.</span><span class="n">open_database</span><span class="p">(</span><span class="s2">&#34;localhost:3141&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">yield</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.fixture</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_db</span><span class="p">(</span><span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Clean database for each test.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Setup: Create test data</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u1:User {id: 1, name: &#39;Alice&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u2:User {id: 2, name: &#39;Bob&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u1)-[:FRIENDS_WITH]-&gt;(u2) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">yield</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Teardown: Clean up</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;MATCH (n) DETACH DELETE n&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_find_friends</span><span class="p">(</span><span class="n">test_db</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test friend recommendation query.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">test_db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (me:User {name: &#39;Alice&#39;})-[:FRIENDS_WITH]-&gt;(friend) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN friend.name </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;friend.name&#34;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;Bob&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_transaction_rollback</span><span class="p">(</span><span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test transaction rollback behavior.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">tx</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;CREATE (u:User </span><span class="si">{id: 999}</span><span class="s2">)&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Simulate error</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&#34;Test error&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">pass</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Verify rollback</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;MATCH (u:User </span><span class="si">{id: 999}</span><span class="s2">) RETURN u&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> </span></span></code></pre></div><p><strong>Go application tests</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">myapp_test</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;context&#34;</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;testing&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="s">&#34;geodedb.com/geode&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">setupTestDB</span><span class="p">(</span><span class="nx">t</span> <span class="o">*</span><span class="nx">testing</span><span class="p">.</span><span class="nx">T</span><span class="p">)</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">DB</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">db</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">geode</span><span class="p">.</span><span class="nf">Connect</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="s">&#34;localhost:3141&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Failed to connect: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Clean database </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">_</span><span class="p">,</span> <span class="nx">err</span> <span class="p">=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">Exec</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="s">&#34;MATCH (n) DETACH DELETE n&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Failed to clean database: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">db</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">TestFindFriends</span><span class="p">(</span><span class="nx">t</span> <span class="o">*</span><span class="nx">testing</span><span class="p">.</span><span class="nx">T</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">db</span> <span class="o">:=</span> <span class="nf">setupTestDB</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">db</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">ctx</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Setup test data </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">_</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">Exec</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">` </span></span></span><span class="line"><span class="cl"><span class="s"> CREATE (u1:User {id: 1, name: &#39;Alice&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s"> CREATE (u2:User {id: 2, name: &#39;Bob&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s"> CREATE (u1)-[:FRIENDS_WITH]-&gt;(u2) </span></span></span><span class="line"><span class="cl"><span class="s"> `</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Failed to create test data: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Test query </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">rows</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">Query</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">` </span></span></span><span class="line"><span class="cl"><span class="s"> MATCH (me:User {name: &#39;Alice&#39;})-[:FRIENDS_WITH]-&gt;(friend) </span></span></span><span class="line"><span class="cl"><span class="s"> RETURN friend.name </span></span></span><span class="line"><span class="cl"><span class="s"> `</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Query failed: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">rows</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">count</span> <span class="kt">int</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">rows</span><span class="p">.</span><span class="nf">Next</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">name</span> <span class="kt">string</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">rows</span><span class="p">.</span><span class="nf">Scan</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">name</span><span class="p">);</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Scan failed: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">name</span> <span class="o">!=</span> <span class="s">&#34;Bob&#34;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;Expected &#39;Bob&#39;, got &#39;%s&#39;&#34;</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">count</span><span class="o">++</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">count</span> <span class="o">!=</span> <span class="mi">1</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">t</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;Expected 1 result, got %d&#34;</span><span class="p">,</span> <span class="nx">count</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="query-testing" class="position-relative d-flex align-items-center group"> <span>Query Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="query-testing" aria-haspopup="dialog" aria-label="Share link: Query Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Test GQL queries in isolation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@pytest.mark.parametrize</span><span class="p">(</span><span class="s2">&#34;query,expected_count&#34;</span><span class="p">,</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="s2">&#34;MATCH (n:User) RETURN n&#34;</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="s2">&#34;MATCH (n:User {name: &#39;Alice&#39;}) RETURN n&#34;</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="s2">&#34;MATCH ()-[r:FRIENDS_WITH]-&gt;() RETURN r&#34;</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> </span></span><span class="line"><span class="cl"><span class="p">])</span> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_basic_queries</span><span class="p">(</span><span class="n">test_db</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">expected_count</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test basic query patterns.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">test_db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">==</span> <span class="n">expected_count</span> </span></span></code></pre></div><p>Test query parameterization:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_parameterized_query</span><span class="p">(</span><span class="n">test_db</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test query with parameters.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">test_db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (u:User {name: $name}) RETURN u.id AS id&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Alice&#34;</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;id&#34;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> </span></span></code></pre></div> <h3 id="integration-testing" class="position-relative d-flex align-items-center group"> <span>Integration Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="integration-testing" aria-haspopup="dialog" aria-label="Share link: Integration Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="test-harness" class="position-relative d-flex align-items-center group"> <span>Test Harness</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="test-harness" aria-haspopup="dialog" aria-label="Share link: Test Harness"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode provides a cross-client test harness validating all client libraries:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> geode-test-harness </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Setup dependencies</span> </span></span><span class="line"><span class="cl">make setup </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Run tests for specific client</span> </span></span><span class="line"><span class="cl">make test-python </span></span><span class="line"><span class="cl">make test-go </span></span><span class="line"><span class="cl">make test-rust </span></span><span class="line"><span class="cl">make test-zig </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Run all tests with reports</span> </span></span><span class="line"><span class="cl">make test-all </span></span><span class="line"><span class="cl">make test-all-html <span class="c1"># Generate HTML reports</span> </span></span></code></pre></div><p>Test categories:</p> <ul> <li><strong>Basic operations</strong>: Ping, simple queries, parameters</li> <li><strong>CRUD</strong>: Node and relationship creation, updates, deletion</li> <li><strong>Transactions</strong>: ACID guarantees, rollback, savepoints</li> <li><strong>Aggregations</strong>: COUNT, SUM, AVG, MIN, MAX</li> <li><strong>Advanced</strong>: Patterns, variable-length paths, subqueries</li> <li><strong>Concurrency</strong>: Parallel queries, transaction conflicts</li> <li><strong>Data types</strong>: Null handling, lists, maps, temporal types</li> </ul> <h4 id="end-to-end-testing" class="position-relative d-flex align-items-center group"> <span>End-to-End Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="end-to-end-testing" aria-haspopup="dialog" aria-label="Share link: End-to-End Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Test complete application workflows:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_user_registration_workflow</span><span class="p">(</span><span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test complete user registration and login workflow.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 1: Register user</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u:User { </span></span></span><span class="line"><span class="cl"><span class="s2"> id: $id, </span></span></span><span class="line"><span class="cl"><span class="s2"> email: $email, </span></span></span><span class="line"><span class="cl"><span class="s2"> password_hash: $password_hash, </span></span></span><span class="line"><span class="cl"><span class="s2"> created: current_timestamp() </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="mi">123</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;[email protected]&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;password_hash&#34;</span><span class="p">:</span> <span class="n">hash_password</span><span class="p">(</span><span class="s2">&#34;password123&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 2: Verify user exists</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User {email: $email}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN u.id, u.email </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;[email protected]&#34;</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;u.id&#34;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">123</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 3: Create user session</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">tx</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User {id: $user_id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (s:Session { </span></span></span><span class="line"><span class="cl"><span class="s2"> id: $session_id, </span></span></span><span class="line"><span class="cl"><span class="s2"> user_id: $user_id, </span></span></span><span class="line"><span class="cl"><span class="s2"> created: current_timestamp(), </span></span></span><span class="line"><span class="cl"><span class="s2"> expires: current_timestamp() + INTERVAL &#39;24&#39; HOUR </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u)-[:HAS_SESSION]-&gt;(s) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;user_id&#34;</span><span class="p">:</span> <span class="mi">123</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;session_id&#34;</span><span class="p">:</span> <span class="s2">&#34;sess_abc123&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 4: Verify session created</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User {id: $user_id})-[:HAS_SESSION]-&gt;(s:Session) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE s.expires &gt; current_timestamp() </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN s.id </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s2">&#34;user_id&#34;</span><span class="p">:</span> <span class="mi">123</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;s.id&#34;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;sess_abc123&#34;</span> </span></span></code></pre></div> <h3 id="performance-testing" class="position-relative d-flex align-items-center group"> <span>Performance Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-testing" aria-haspopup="dialog" aria-label="Share link: Performance Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="benchmarking-queries" class="position-relative d-flex align-items-center group"> <span>Benchmarking Queries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="benchmarking-queries" aria-haspopup="dialog" aria-label="Share link: Benchmarking Queries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Measure query performance:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">statistics</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">benchmark_query</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">iterations</span><span class="o">=</span><span class="mi">100</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Benchmark query execution time.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">times</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">iterations</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">times</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">)</span> <span class="c1"># Convert to ms</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;mean&#34;</span><span class="p">:</span> <span class="n">statistics</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">times</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;median&#34;</span><span class="p">:</span> <span class="n">statistics</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="n">times</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;stdev&#34;</span><span class="p">:</span> <span class="n">statistics</span><span class="o">.</span><span class="n">stdev</span><span class="p">(</span><span class="n">times</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;min&#34;</span><span class="p">:</span> <span class="nb">min</span><span class="p">(</span><span class="n">times</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;max&#34;</span><span class="p">:</span> <span class="nb">max</span><span class="p">(</span><span class="n">times</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;p95&#34;</span><span class="p">:</span> <span class="n">statistics</span><span class="o">.</span><span class="n">quantiles</span><span class="p">(</span><span class="n">times</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="mi">20</span><span class="p">)[</span><span class="mi">18</span><span class="p">],</span> <span class="c1"># 95th percentile</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;p99&#34;</span><span class="p">:</span> <span class="n">statistics</span><span class="o">.</span><span class="n">quantiles</span><span class="p">(</span><span class="n">times</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="mi">100</span><span class="p">)[</span><span class="mi">98</span><span class="p">],</span> <span class="c1"># 99th percentile</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_query_performance</span><span class="p">(</span><span class="n">test_db</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test query performance meets SLA.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">stats</span> <span class="o">=</span> <span class="k">await</span> <span class="n">benchmark_query</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">test_db</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (u:User {id: $id}) RETURN u&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Assert performance SLAs</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">stats</span><span class="p">[</span><span class="s2">&#34;p95&#34;</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mf">10.0</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&#34;P95 latency </span><span class="si">{</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;p95&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">ms exceeds 10ms SLA&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">stats</span><span class="p">[</span><span class="s2">&#34;p99&#34;</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mf">50.0</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&#34;P99 latency </span><span class="si">{</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;p99&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">ms exceeds 50ms SLA&#34;</span> </span></span></code></pre></div> <h4 id="load-testing" class="position-relative d-flex align-items-center group"> <span>Load Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="load-testing" aria-haspopup="dialog" aria-label="Share link: Load Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Test system under load:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">asyncio</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">load_test</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">concurrent_queries</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">duration_seconds</span><span class="o">=</span><span class="mi">60</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Run load test with concurrent queries.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">worker</span><span class="p">(</span><span class="n">worker_id</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Worker executing queries.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">queries_executed</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> <span class="n">errors</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> <span class="n">start_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">while</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start_time</span> <span class="o">&lt;</span> <span class="n">duration_seconds</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (u:User {id: $id}) RETURN u&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="n">worker_id</span> <span class="o">%</span> <span class="mi">1000</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">queries_executed</span> <span class="o">+=</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">errors</span> <span class="o">+=</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;worker_id&#34;</span><span class="p">:</span> <span class="n">worker_id</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;queries&#34;</span><span class="p">:</span> <span class="n">queries_executed</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;errors&#34;</span><span class="p">:</span> <span class="n">errors</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Run workers concurrently</span> </span></span><span class="line"><span class="cl"> <span class="n">tasks</span> <span class="o">=</span> <span class="p">[</span><span class="n">worker</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">concurrent_queries</span><span class="p">)]</span> </span></span><span class="line"><span class="cl"> <span class="n">results</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Aggregate results</span> </span></span><span class="line"><span class="cl"> <span class="n">total_queries</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="s2">&#34;queries&#34;</span><span class="p">]</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">results</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">total_errors</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="s2">&#34;errors&#34;</span><span class="p">]</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">results</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">qps</span> <span class="o">=</span> <span class="n">total_queries</span> <span class="o">/</span> <span class="n">duration_seconds</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;total_queries&#34;</span><span class="p">:</span> <span class="n">total_queries</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;total_errors&#34;</span><span class="p">:</span> <span class="n">total_errors</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;error_rate&#34;</span><span class="p">:</span> <span class="n">total_errors</span> <span class="o">/</span> <span class="n">total_queries</span> <span class="k">if</span> <span class="n">total_queries</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;queries_per_second&#34;</span><span class="p">:</span> <span class="n">qps</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_load_performance</span><span class="p">(</span><span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test system under load.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">results</span> <span class="o">=</span> <span class="k">await</span> <span class="n">load_test</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">concurrent_queries</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">duration_seconds</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">baseline_qps</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># Set based on your benchmark baseline</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">results</span><span class="p">[</span><span class="s2">&#34;error_rate&#34;</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mf">0.01</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&#34;Error rate </span><span class="si">{</span><span class="n">results</span><span class="p">[</span><span class="s1">&#39;error_rate&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> exceeds 1%&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">results</span><span class="p">[</span><span class="s2">&#34;queries_per_second&#34;</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">baseline_qps</span><span class="p">,</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="sa">f</span><span class="s2">&#34;QPS </span><span class="si">{</span><span class="n">results</span><span class="p">[</span><span class="s1">&#39;queries_per_second&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> below baseline </span><span class="si">{</span><span class="n">baseline_qps</span><span class="si">}</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span></code></pre></div> <h3 id="testing-best-practices" class="position-relative d-flex align-items-center group"> <span>Testing Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing-best-practices" aria-haspopup="dialog" aria-label="Share link: Testing Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="isolation" class="position-relative d-flex align-items-center group"> <span>Isolation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="isolation" aria-haspopup="dialog" aria-label="Share link: Isolation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Ensure test isolation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@pytest.fixture</span><span class="p">(</span><span class="n">scope</span><span class="o">=</span><span class="s2">&#34;function&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">isolated_db</span><span class="p">(</span><span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Create isolated test database.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Each test gets clean state</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;MATCH (n) DETACH DELETE n&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">yield</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;MATCH (n) DETACH DELETE n&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="determinism" class="position-relative d-flex align-items-center group"> <span>Determinism</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="determinism" aria-haspopup="dialog" aria-label="Share link: Determinism"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Make tests deterministic:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Bad: Non-deterministic due to timestamp</span> </span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u:User {created: current_timestamp()}) </span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Good: Use fixed timestamps in tests</span> </span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u:User {created: timestamp(&#39;2026-01-24T10:00:00Z&#39;)}) </span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="test-data-management" class="position-relative d-flex align-items-center group"> <span>Test Data Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="test-data-management" aria-haspopup="dialog" aria-label="Share link: Test Data Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Manage test data effectively:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">TestDataFactory</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Factory for creating test data.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nd">@staticmethod</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Create test user with defaults.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">defaults</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Test User&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;[email protected]&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="n">user_data</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">defaults</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (u:User { </span></span></span><span class="line"><span class="cl"><span class="s2"> id: $id, </span></span></span><span class="line"><span class="cl"><span class="s2"> name: $name, </span></span></span><span class="line"><span class="cl"><span class="s2"> email: $email </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="n">user_data</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">user_data</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_with_factory</span><span class="p">(</span><span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Test using data factory.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">user</span> <span class="o">=</span> <span class="k">await</span> <span class="n">TestDataFactory</span><span class="o">.</span><span class="n">create_user</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">client</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nb">id</span><span class="o">=</span><span class="mi">123</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">name</span><span class="o">=</span><span class="s2">&#34;Alice&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (u:User {id: $id}) RETURN u.name&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="n">user</span><span class="p">[</span><span class="s2">&#34;id&#34;</span><span class="p">]}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;u.name&#34;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;Alice&#34;</span> </span></span></code></pre></div> <h3 id="continuous-integration" class="position-relative d-flex align-items-center group"> <span>Continuous Integration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="continuous-integration" aria-haspopup="dialog" aria-label="Share link: Continuous Integration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="github-actions" class="position-relative d-flex align-items-center group"> <span>GitHub Actions</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="github-actions" aria-haspopup="dialog" aria-label="Share link: GitHub Actions"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Tests</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">push, pull_request]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">test</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">services</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">codepros/geode:latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="m">3141</span><span class="p">:</span><span class="m">3141</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">options</span><span class="p">:</span><span class="w"> </span><span class="p">&gt;-</span><span class="sd"> </span></span></span><span class="line"><span class="cl"><span class="sd"> --health-cmd &#34;/usr/local/bin/geode ping&#34; </span></span></span><span class="line"><span class="cl"><span class="sd"> --health-interval 10s </span></span></span><span class="line"><span class="cl"><span class="sd"> --health-timeout 5s </span></span></span><span class="line"><span class="cl"><span class="sd"> --health-retries 5</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Set up Python</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/setup-python@v4</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">python-version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;3.11&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Install dependencies</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd"> </span></span></span><span class="line"><span class="cl"><span class="sd"> pip install -r requirements.txt </span></span></span><span class="line"><span class="cl"><span class="sd"> pip install pytest pytest-asyncio pytest-cov</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run tests</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd"> </span></span></span><span class="line"><span class="cl"><span class="sd"> pytest --cov=myapp --cov-report=xml tests/</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Upload coverage</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">codecov/codecov-action@v3</span><span class="w"> </span></span></span></code></pre></div> <h4 id="gitlab-ci" class="position-relative d-flex align-items-center group"> <span>GitLab CI</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="gitlab-ci" aria-haspopup="dialog" aria-label="Share link: GitLab CI"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">test</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">python:3.11</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">services</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">codepros/geode:latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">alias</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">variables</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">GEODE_HOST</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">GEODE_PORT</span><span class="p">:</span><span class="w"> </span><span class="m">3141</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">before_script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">pip install -r requirements.txt pytest pytest-cov</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">pytest --cov=myapp tests/</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">coverage</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;/TOTAL.*\s+(\d+%)$/&#39;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/tags/debugging/" >Debugging</a> - Troubleshooting techniques</li> <li><a href="/categories/performance-and-scaling/" >Performance</a> - Performance testing</li> <li><a href="/categories/development/" >Development</a> - Development workflow</li> <li><a href="/tags/best-practices/" >Quality Assurance</a> - QA practices</li> <li><a href="/tags/devops/" >CI/CD</a> - Continuous integration</li> </ul> <h3 id="further-reading" class="position-relative d-flex align-items-center group"> <span>Further Reading</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="further-reading" aria-haspopup="dialog" aria-label="Share link: Further Reading"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/docs/development/testing-guide/" >Testing Guide</a> - Cross-client testing</li> <li><a href="/docs/performance/benchmarking/" >Performance Benchmarking</a> - Benchmark methodology</li> <li><a href="/docs/development/governance/" >Governance Guide</a> - Evidence-based development with CANARY markers</li> </ul>

Related Articles