<?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: Saptarshi Niyogi</title>
    <description>The latest articles on DEV Community by Saptarshi Niyogi (@saptarshi_niyogi).</description>
    <link>https://dev.to/saptarshi_niyogi</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4103306%2Ff1801f27-c2cb-459c-9196-fad43929c4b2.jpg</url>
      <title>DEV Community: Saptarshi Niyogi</title>
      <link>https://dev.to/saptarshi_niyogi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saptarshi_niyogi"/>
    <language>en</language>
    <item>
      <title>Your React Tests Execute the UI. But Do They Verify It?</title>
      <dc:creator>Saptarshi Niyogi</dc:creator>
      <pubDate>Tue, 01 Sep 2026 17:09:17 +0000</pubDate>
      <link>https://dev.to/saptarshi_niyogi/your-react-tests-execute-the-ui-but-do-they-verify-it-2p7m</link>
      <guid>https://dev.to/saptarshi_niyogi/your-react-tests-execute-the-ui-but-do-they-verify-it-2p7m</guid>
      <description>&lt;h1&gt;
  
  
  Your React Tests Execute the UI. But Do They Verify It?
&lt;/h1&gt;

&lt;p&gt;Passing tests and high code coverage can still leave important UI behavior unproven.&lt;/p&gt;

&lt;p&gt;That sounds counterintuitive at first.&lt;/p&gt;

&lt;p&gt;If the test passes, the component rendered, the button was clicked, and the relevant code executed, what exactly is missing?&lt;/p&gt;

&lt;p&gt;The answer is often the &lt;strong&gt;behavioral oracle&lt;/strong&gt;: the assertion that proves the expected observable outcome actually happened.&lt;/p&gt;

&lt;p&gt;That distinction is what led me to build an open-source project called &lt;a href="https://github.com/sapniyogi/ui-behavior-coverage" rel="noopener noreferrer"&gt;&lt;code&gt;ui-behavior-coverage&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It explores a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Did the test explicitly verify the UI behavior it exercised?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  A test can exercise behavior without verifying it
&lt;/h2&gt;

&lt;p&gt;Consider a simple React component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SaveButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&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;SaveButton&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;SaveButtonProps&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="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Save
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;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 imagine this test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;handles a disabled button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;onSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SaveButton&lt;/span&gt;
      &lt;span class="na"&gt;disabled&lt;/span&gt;
      &lt;span class="na"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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="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="s1"&gt;Save&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;renders the component;&lt;/li&gt;
&lt;li&gt;provides &lt;code&gt;disabled&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;finds the button;&lt;/li&gt;
&lt;li&gt;attempts the interaction;&lt;/li&gt;
&lt;li&gt;executes the relevant test path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But what behavior did it actually prove?&lt;/p&gt;

&lt;p&gt;The important contract here is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When the button is disabled, clicking it should not invoke &lt;code&gt;onSave&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The test never checks that.&lt;/p&gt;

&lt;p&gt;A stronger test adds the missing oracle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;does not save when disabled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;onSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SaveButton&lt;/span&gt;
      &lt;span class="na"&gt;disabled&lt;/span&gt;
      &lt;span class="na"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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="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="s1"&gt;Save&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&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;Both tests interact with almost the same implementation.&lt;/p&gt;

&lt;p&gt;But only the second test explicitly verifies the expected behavior.&lt;/p&gt;

&lt;p&gt;That difference is easy for ordinary execution coverage to miss.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code coverage is answering a different question
&lt;/h2&gt;

&lt;p&gt;Traditional code coverage is extremely valuable.&lt;/p&gt;

&lt;p&gt;Line coverage asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did this line execute?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Branch coverage asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Were both sides of this conditional traversed?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Function coverage asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Was this function called?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are useful signals.&lt;/p&gt;

&lt;p&gt;But they do not necessarily tell us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did the test prove the behavior that mattered?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That led me to separate three concepts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Coverage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the implementation execute?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Behavior Reach
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the test actually exercise the UI behavior?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Behavior Verification
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the test explicitly prove the expected outcome?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A test can therefore reach a behavior without verifying it.&lt;/p&gt;

&lt;p&gt;That is the gap &lt;code&gt;ui-behavior-coverage&lt;/code&gt;, or UBC, is designed to make visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  DISCOVERED, EXERCISED, and VERIFIED
&lt;/h2&gt;

&lt;p&gt;UBC classifies supported behavioral contracts using three states.&lt;/p&gt;

&lt;h3&gt;
  
  
  DISCOVERED
&lt;/h3&gt;

&lt;p&gt;The analyzer found a behavior in the component, but the test did not establish evidence that it reached that behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  EXERCISED
&lt;/h3&gt;

&lt;p&gt;The test reached or interacted with the behavior, but no matching verification was found.&lt;/p&gt;

&lt;h3&gt;
  
  
  VERIFIED
&lt;/h3&gt;

&lt;p&gt;The behavior was reached and the test contains explicit matching evidence for the expected result.&lt;/p&gt;

&lt;p&gt;For the disabled-button example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Weak test

Behavior:
disabled=true -&amp;gt; click suppression

Reached:     yes
Verified:    no

Status: EXERCISED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the same behavioral contract becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reached:     yes
Verified:    yes

Status: VERIFIED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Weak oracles are surprisingly easy to write
&lt;/h2&gt;

&lt;p&gt;The problem is not limited to disabled buttons.&lt;/p&gt;

&lt;p&gt;Consider a checkbox.&lt;/p&gt;

&lt;p&gt;A test might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkbox&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This proves that some callback happened.&lt;/p&gt;

&lt;p&gt;But if the intended behavior is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unchecked -&amp;gt; checked
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then the assertion does not necessarily prove the expected transition.&lt;/p&gt;

&lt;p&gt;A stronger callback assertion might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectContaining&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="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectContaining&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or the observable evidence could be rendered DOM state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkbox&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeChecked&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same principle applies to many common UI behaviors.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeDisabled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expected value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dialog&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aria-expanded&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;true&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;The important question is not simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did the test interact with the component?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What observable behavior did the test actually prove?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why this matters even more with AI-generated tests
&lt;/h2&gt;

&lt;p&gt;AI coding assistants can produce tests extremely quickly.&lt;/p&gt;

&lt;p&gt;They can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scaffold test files;&lt;/li&gt;
&lt;li&gt;identify components;&lt;/li&gt;
&lt;li&gt;create mocks;&lt;/li&gt;
&lt;li&gt;use Testing Library;&lt;/li&gt;
&lt;li&gt;click controls;&lt;/li&gt;
&lt;li&gt;generate assertions;&lt;/li&gt;
&lt;li&gt;increase traditional code coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That productivity is useful.&lt;/p&gt;

&lt;p&gt;But it also creates an interesting test-quality problem.&lt;/p&gt;

&lt;p&gt;A generated test can look sophisticated while still containing weak behavioral evidence.&lt;/p&gt;

&lt;p&gt;For example, an AI-generated test may:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ compile
✓ render the component
✓ click the right control
✓ call the expected mock
✓ pass in Jest or Vitest
✓ increase line coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while still failing to verify the actual UI outcome.&lt;/p&gt;

&lt;p&gt;UBC does &lt;strong&gt;not&lt;/strong&gt; try to detect whether a test was written by a human or an LLM.&lt;/p&gt;

&lt;p&gt;That distinction is not important for the analyzer.&lt;/p&gt;

&lt;p&gt;Instead, it evaluates the resulting test evidence.&lt;/p&gt;

&lt;p&gt;This creates a potentially useful separation of responsibilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI coding assistant
        ↓
generates tests
        ↓
Jest / Vitest
        ↓
does the test pass?
        ↓
Code coverage
        ↓
did implementation execute?
        ↓
UI Behavior Coverage
        ↓
did the test verify the behavior?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The origin of the test does not matter.&lt;/p&gt;

&lt;p&gt;The quality of the evidence does.&lt;/p&gt;




&lt;h2&gt;
  
  
  What UBC currently analyzes
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ui-behavior-coverage&lt;/code&gt; is a static analyzer for React component tests.&lt;/p&gt;

&lt;p&gt;The current stable release is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; ui-behavior-coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then scan a project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ui-behavior-coverage scan &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or generate JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ui-behavior-coverage scan &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also analyze a single component/test pair:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ui-behavior-coverage analyze &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--component&lt;/span&gt; src/SaveButton.tsx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--test&lt;/span&gt; src/SaveButton.test.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UBC does not execute the application.&lt;/p&gt;

&lt;p&gt;It performs conservative static analysis over supported React production and test patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  Material UI is currently a first-class semantic provider
&lt;/h2&gt;

&lt;p&gt;The current implementation includes first-class Material UI semantics.&lt;/p&gt;

&lt;p&gt;Supported areas include a conservative subset of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;native button disabled-event suppression;&lt;/li&gt;
&lt;li&gt;MUI &lt;code&gt;Button&lt;/code&gt; disabled/loading behavior;&lt;/li&gt;
&lt;li&gt;rendered disabled state;&lt;/li&gt;
&lt;li&gt;controlled &lt;code&gt;Checkbox&lt;/code&gt; behavior;&lt;/li&gt;
&lt;li&gt;controlled &lt;code&gt;Switch&lt;/code&gt; behavior;&lt;/li&gt;
&lt;li&gt;standalone &lt;code&gt;Radio&lt;/code&gt; behavior;&lt;/li&gt;
&lt;li&gt;controlled &lt;code&gt;TextField&lt;/code&gt; callback/value evidence;&lt;/li&gt;
&lt;li&gt;native-mode MUI &lt;code&gt;Select&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;selected MUI input value state;&lt;/li&gt;
&lt;li&gt;Slider public value state;&lt;/li&gt;
&lt;li&gt;Dialog, Popover, Menu, and Modal visibility;&lt;/li&gt;
&lt;li&gt;selected public &lt;code&gt;aria-*&lt;/code&gt; state;&lt;/li&gt;
&lt;li&gt;React Admin / React Hook Form style bindings;&lt;/li&gt;
&lt;li&gt;simple local wrappers;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;styled()&lt;/code&gt; wrappers;&lt;/li&gt;
&lt;li&gt;barrel exports;&lt;/li&gt;
&lt;li&gt;TypeScript path aliases;&lt;/li&gt;
&lt;li&gt;Testing Library &lt;code&gt;rerender()&lt;/code&gt; state evidence;&lt;/li&gt;
&lt;li&gt;statically safe local render helpers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The word &lt;strong&gt;conservative&lt;/strong&gt; is important.&lt;/p&gt;

&lt;p&gt;If the analyzer cannot trace a behavior safely, it should leave that case unclassified instead of inventing evidence.&lt;/p&gt;

&lt;p&gt;Precision is more important than producing a large number of findings.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observable behavior versus implementation detail
&lt;/h2&gt;

&lt;p&gt;Real React code often introduces local event handlers.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;onOpenChange&lt;/span&gt;&lt;span class="p"&gt;?.(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
  &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A naive analyzer might treat &lt;code&gt;handleClick&lt;/code&gt; itself as a public behavioral obligation.&lt;/p&gt;

&lt;p&gt;But that function is an implementation detail.&lt;/p&gt;

&lt;p&gt;From the component consumer's perspective, the meaningful observable contract is represented by the public API, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;onOpenChange&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction matters.&lt;/p&gt;

&lt;p&gt;If a static analyzer exposes internal implementation handlers as testing obligations, it can generate false or misleading contracts that users cannot reasonably verify from the public component surface.&lt;/p&gt;

&lt;p&gt;UBC therefore applies precision-oriented rules to suppress supported internal-handler cases.&lt;/p&gt;

&lt;p&gt;The same issue appears with callback payloads.&lt;/p&gt;

&lt;p&gt;Suppose a framework event is transformed before being passed to a public callback.&lt;/p&gt;

&lt;p&gt;The analyzer should not automatically assume that the public consumer receives the original framework event.&lt;/p&gt;

&lt;p&gt;Behavioral verification has to follow the actual observable API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real repositories reveal problems synthetic tests don't
&lt;/h2&gt;

&lt;p&gt;Synthetic fixtures are necessary for unit tests.&lt;/p&gt;

&lt;p&gt;But they are not enough for validating an analyzer like this.&lt;/p&gt;

&lt;p&gt;Real React applications contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nested wrappers;&lt;/li&gt;
&lt;li&gt;barrel exports;&lt;/li&gt;
&lt;li&gt;aliases;&lt;/li&gt;
&lt;li&gt;TypeScript path mappings;&lt;/li&gt;
&lt;li&gt;render helpers;&lt;/li&gt;
&lt;li&gt;dynamic test IDs;&lt;/li&gt;
&lt;li&gt;rerenders;&lt;/li&gt;
&lt;li&gt;local handlers;&lt;/li&gt;
&lt;li&gt;form abstractions;&lt;/li&gt;
&lt;li&gt;different testing conventions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For that reason, I have also been validating UBC against pinned scopes from public open-source React repositories.&lt;/p&gt;

&lt;p&gt;One Phase-B evaluation used a pinned snapshot of Cytoscape Web.&lt;/p&gt;

&lt;p&gt;That evaluation exposed four analyzer limitations involving:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;internal implementation handlers;&lt;/li&gt;
&lt;li&gt;render-state evidence hidden behind local helpers;&lt;/li&gt;
&lt;li&gt;Testing Library &lt;code&gt;rerender()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;exact DOM-property assertions associated with dynamic production &lt;code&gt;data-testid&lt;/code&gt; values.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The important part of the process was the order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;run analyzer
    ↓
manually adjudicate findings
    ↓
freeze expected classifications
    ↓
write regression tests
    ↓
change analyzer
    ↓
rerun validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The corrected analyzer produced the following result for that pinned evaluation scope:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Consumer-facing contracts: 12
Reached contracts:          8
Verified contracts:         1

Behavior Reach:             66.7%
Behavior Verification:       8.3%
Verification Gap:           58.4 percentage points
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those numbers are &lt;strong&gt;not an accuracy score&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They describe one pinned application snapshot and the currently supported semantic surface.&lt;/p&gt;

&lt;p&gt;The useful result was that real-world validation exposed concrete precision problems that synthetic tests had not.&lt;/p&gt;




&lt;h2&gt;
  
  
  Behavior Reach and Behavior Verification
&lt;/h2&gt;

&lt;p&gt;UBC reports two aggregate metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behavior Reach
&lt;/h3&gt;

&lt;p&gt;The percentage of discovered supported behavioral contracts that tests actually reach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behavior Verification
&lt;/h3&gt;

&lt;p&gt;The percentage of discovered supported behavioral contracts with explicit matching verification.&lt;/p&gt;

&lt;p&gt;This allows a third metric:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Verification Gap =
Behavior Reach - Behavior Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Behavior Reach:          78%
Behavior Verification:   51%
Verification Gap:        27 percentage points
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That 27-point gap represents supported behavior that tests are reaching without equivalent explicit verification.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; mean the application is wrong.&lt;/p&gt;

&lt;p&gt;It does not even necessarily mean the tests are bad.&lt;/p&gt;

&lt;p&gt;It means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The analyzer found stronger evidence of behavioral execution than behavioral proof.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is worth reviewing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where UBC fits in the testing stack
&lt;/h2&gt;

&lt;p&gt;I don't see behavioral verification coverage as a replacement for existing tools.&lt;/p&gt;

&lt;p&gt;They answer different questions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jest / Vitest
    ↓
Does the test pass?

Istanbul / V8 coverage
    ↓
Did the implementation execute?

Testing Library
    ↓
How does the test interact with observable UI?

UI Behavior Coverage
    ↓
Did the test explicitly verify
the behavior it exercised?

Mutation testing
    ↓
Can deliberate implementation changes
survive the test suite?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A mature testing strategy can use several of these signals together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not just use mutation testing?
&lt;/h2&gt;

&lt;p&gt;Mutation testing is one of the strongest techniques available for evaluating test-suite quality.&lt;/p&gt;

&lt;p&gt;A mutation tool deliberately changes the implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might conceptually become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then checks whether the test suite detects the change.&lt;/p&gt;

&lt;p&gt;That is powerful.&lt;/p&gt;

&lt;p&gt;Behavioral verification coverage is addressing a different problem.&lt;/p&gt;

&lt;p&gt;UBC attempts to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this test contain explicit evidence for this supported UI behavior?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;without repeatedly modifying and executing the application.&lt;/p&gt;

&lt;p&gt;The approaches can complement each other.&lt;/p&gt;

&lt;p&gt;Mutation testing measures whether tests detect implementation changes.&lt;/p&gt;

&lt;p&gt;Behavioral verification analysis inspects whether expected observable outcomes are explicitly represented in the tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why static analysis?
&lt;/h2&gt;

&lt;p&gt;Static analysis has useful properties for this problem.&lt;/p&gt;

&lt;p&gt;It can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast;&lt;/li&gt;
&lt;li&gt;deterministic;&lt;/li&gt;
&lt;li&gt;local;&lt;/li&gt;
&lt;li&gt;CI-friendly;&lt;/li&gt;
&lt;li&gt;independent of browser execution;&lt;/li&gt;
&lt;li&gt;inspectable;&lt;/li&gt;
&lt;li&gt;reproducible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it also has limitations.&lt;/p&gt;

&lt;p&gt;A static analyzer cannot safely understand every possible React architecture.&lt;/p&gt;

&lt;p&gt;UBC intentionally does not claim support for arbitrary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hooks;&lt;/li&gt;
&lt;li&gt;contexts;&lt;/li&gt;
&lt;li&gt;effects;&lt;/li&gt;
&lt;li&gt;state machines;&lt;/li&gt;
&lt;li&gt;browser layout;&lt;/li&gt;
&lt;li&gt;portals;&lt;/li&gt;
&lt;li&gt;computed CSS;&lt;/li&gt;
&lt;li&gt;animation timing;&lt;/li&gt;
&lt;li&gt;arbitrary custom form abstractions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unsupported behavior should remain unsupported until there is a sufficiently precise rule.&lt;/p&gt;

&lt;p&gt;I would rather have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;no classification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;than a confident-looking but misleading one.&lt;/p&gt;




&lt;h2&gt;
  
  
  JSON output is versioned
&lt;/h2&gt;

&lt;p&gt;For automation, UBC exposes versioned JSON.&lt;/p&gt;

&lt;p&gt;Example:&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="nl"&gt;"schemaVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"toolVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reportType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"summary"&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;"discovered"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"exercised"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"verified"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"behaviorReach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;22.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"behaviorVerification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"verificationGap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.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="nl"&gt;"report"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intent is to make the analyzer usable from scripts and CI systems without depending entirely on human-readable CLI output.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I want to build next
&lt;/h2&gt;

&lt;p&gt;The current &lt;code&gt;0.1.0&lt;/code&gt; release establishes the first stable semantic surface.&lt;/p&gt;

&lt;p&gt;The next phase is less about adding a huge number of UI-library rules and more about making behavioral verification useful in normal development workflows.&lt;/p&gt;

&lt;p&gt;Some areas I am considering include:&lt;/p&gt;

&lt;h3&gt;
  
  
  Baseline support
&lt;/h3&gt;

&lt;p&gt;A mature project may already contain many verification gaps.&lt;/p&gt;

&lt;p&gt;Requiring teams to fix every historical gap before adopting the tool would create unnecessary friction.&lt;/p&gt;

&lt;p&gt;A more useful workflow would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;record existing baseline
        ↓
allow existing gaps
        ↓
fail only when new gaps are introduced
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CI policies
&lt;/h3&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ubc scan &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--fail-on-new-gaps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or configurable verification thresholds.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub integration
&lt;/h3&gt;

&lt;p&gt;PR annotations could surface behavioral verification gaps directly during code review.&lt;/p&gt;

&lt;h3&gt;
  
  
  SARIF output
&lt;/h3&gt;

&lt;p&gt;This could allow UBC findings to participate in existing static-analysis and code-scanning workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better explanations
&lt;/h3&gt;

&lt;p&gt;If a behavior is classified as &lt;code&gt;EXERCISED&lt;/code&gt;, the tool should eventually be able to explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production behavior:
disabled=true -&amp;gt; callback suppression

Test evidence:
disabled=true rendered
button interaction detected

Missing evidence:
no matching suppression assertion found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coding-agent feedback loops
&lt;/h3&gt;

&lt;p&gt;One especially interesting direction is using UBC as an independent evaluator for AI-generated tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI generates test
      ↓
test passes
      ↓
UBC finds weak verification
      ↓
AI strengthens test
      ↓
UBC rechecks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is still future work, but I think it is an interesting use case for behavioral test analysis.&lt;/p&gt;




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

&lt;p&gt;The package is available on npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; ui-behavior-coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scan a React project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ui-behavior-coverage scan &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://github.com/sapniyogi/ui-behavior-coverage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;npm:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://www.npmjs.com/package/ui-behavior-coverage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The project is open source under the MIT license.&lt;/p&gt;




&lt;h2&gt;
  
  
  I am especially interested in failure cases
&lt;/h2&gt;

&lt;p&gt;At this stage, feedback that exposes analyzer limitations is more useful than simply adding more component patterns.&lt;/p&gt;

&lt;p&gt;If you try UBC, I would particularly like to see examples where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a meaningful behavior was missed;&lt;/li&gt;
&lt;li&gt;implementation detail was incorrectly surfaced as a contract;&lt;/li&gt;
&lt;li&gt;a strong assertion was classified as only &lt;code&gt;EXERCISED&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;a wrapper pattern could not be resolved;&lt;/li&gt;
&lt;li&gt;a behavior was classified &lt;code&gt;VERIFIED&lt;/code&gt; when it should not have been.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those cases help improve the precision model.&lt;/p&gt;




&lt;h2&gt;
  
  
  One final question
&lt;/h2&gt;

&lt;p&gt;Modern frontend testing has become very good at answering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did the test run successfully?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Coverage tooling is very good at answering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How much implementation code did the test execute?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As AI makes it cheaper to generate more code, more tests, and more assertions, I think another question becomes increasingly important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What did those tests actually prove?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the question I am exploring with UI Behavior Coverage.&lt;/p&gt;

</description>
      <category>react</category>
      <category>testing</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
