Giter VIP home page Giter VIP logo

sniffy's Introduction

Sniffy

Join the chat at https://gitter.im/sniffy/sniffy CI Status Coverage Status Maven Central Download License

Sniffy counts the number of executed SQL queries and provides an API for validating them It is designed for unit tests and allows you to test if particular method doesn't make more than N SQL queries Especially it's useful to catch the ORM N+1 problem at early stages

try (Spy s = Sniffer.expectAtMostOnce(Query.SELECT).expectNever(Threads.OTHERS);
     Statement statement = connection.createStatement()) {
    statement.execute("SELECT 1 FROM DUAL");
    // Sniffy will throw an Exception if you execute query other than SELECT or uncomment line below
    //statement.execute("SELECT 1 FROM DUAL");
}

You can also use Sniffy in your test environments to see the number of SQL queries executed by each HTTP request. Just add it to your web.xml file:

<filter>
    <filter-name>sniffer</filter-name>
    <filter-class>io.sniffy.servlet.SnifferFilter</filter-class>
    <init-param>
        <param-name>inject-html</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>sniffer</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Restart your server and you will see the number of queries in bottom right corner of your app:

RecordedDemo

Live Demo - http://demo.sniffy.io/

Maven

Sniffy is available from Maven Central repository

<dependency>
    <groupId>io.sniffy</groupId>
    <artifactId>sniffy</artifactId>
    <version>3.0.3</version>
</dependency>

For Gradle users:

dependencies {
    compile 'io.sniffy:sniffy:3.0.3'
}

Download

Get automatic notifications about new "sniffy" versions

Setup

Simply add sniffy.jar to your classpath and add sniffer: prefix to the JDBC connection url For example jdbc:h2:~/test should be changed to sniffer:jdbc:h2:mem: The sniffer JDBC driver class name is io.sniffy.MockDriver

HTML injection is configured in web.xml file:

<filter>
    <filter-name>sniffer</filter-name>
    <filter-class>io.sniffy.servlet.SnifferFilter</filter-class>
    <init-param>
        <!-- 
        Enables injection of Sniffy toolbar to HTML
        If disabled the html remains untouched
        You still can get the number of executed queries from X-Sql-Queries HTTP header
         -->
        <param-name>inject-html</param-name>
        <param-value>true</param-value> <!-- default: false -->
    </init-param>
    <init-param>
        <!-- Allows disabling the Sniffy filter in web.xml -->
        <param-name>enabled</param-name>
        <param-value>true</param-value> <!-- default: true -->
    </init-param>
    <init-param>
        <!-- Allows excluding some of the request URL's from Sniffer filter -->
        <param-name>exclude-pattern</param-name>
        <param-value>^/vets.html$</param-value> <!-- optional -->
    </init-param>
</filter>
<filter-mapping>
    <filter-name>sniffer</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Usage

Following test shows the main ways of integrating Sniffy into your project:

import io.sniffy.Sniffer;
import io.sniffy.Spy;
import io.sniffy.Threads;
import io.sniffy.Expectation;
import io.sniffy.junit.QueryCounter;
import org.junit.Rule;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import static org.junit.Assert.*;

public class UsageTest {

    @Test
    public void testVerifyApi() throws SQLException {
        // Just add sniffer: in front of your JDBC connection URL in order to enable sniffer
        Connection connection = DriverManager.getConnection("sniffer:jdbc:h2:mem:", "sa", "sa");
        // Spy holds the amount of queries executed till the given amount of time
        // It acts as a base for further assertions
        Spy spy = Sniffer.spy();
        // You do not need to modify your JDBC code
        connection.createStatement().execute("SELECT 1 FROM DUAL");
        assertEquals(1, spy.executedStatements());
        // Sniffer.verifyAtMostOnce() throws an AssertionError if more than one query was executed;
        spy.verifyAtMostOnce();
        // Sniffer.verifyNever(Threads.OTHERS) throws an AssertionError if at least one query was executed
        // by the thread other than then current one
        spy.verifyNever(Threads.OTHERS);
    }

    @Test
    public void testFunctionalApi() throws SQLException {
        // Just add sniffer: in front of your JDBC connection URL in order to enable sniffer
        final Connection connection = DriverManager.getConnection("sniffer:jdbc:h2:mem:", "sa", "sa");
        // Sniffer.execute() method executes the lambda expression and returns an instance of Spy
        // which provides methods for validating the number of executed queries in given lambda
        Sniffer.execute(() -> connection.createStatement().execute("SELECT 1 FROM DUAL")).verifyAtMostOnce();
    }

    @Test
    public void testResourceApi() throws SQLException {
        // Just add sniffer: in front of your JDBC connection URL in order to enable sniffer
        final Connection connection = DriverManager.getConnection("sniffer:jdbc:h2:mem:", "sa", "sa");
        // You can use Sniffer in a try-with-resource block using expect methods instead of verify
        // When the try-with-resource block is completed, JDBC Sniffer will verify all the expectations defined
        try (@SuppressWarnings("unused") Spy s = Sniffer.expectAtMostOnce().expectNever(Threads.OTHERS);
             Statement statement = connection.createStatement()) {
            statement.execute("SELECT 1 FROM DUAL");
        }
    }

    // Integrate Sniffy to your test using @Rule annotation and a QueryCounter field
    @Rule
    public final QueryCounter queryCounter = new QueryCounter();

    // Now just add @Expectation or @Expectations annotations to define number of queries allowed for given method
    @Test
    @Expectation(1)
    public void testJUnitIntegration() throws SQLException {
        // Just add sniffer: in front of your JDBC connection URL in order to enable sniffer
        final Connection connection = DriverManager.getConnection("sniffer:jdbc:h2:mem:", "sa", "sa");
        // Do not make any changes in your code - just add the @Rule QueryCounter and put annotations on your test method
        connection.createStatement().execute("SELECT 1 FROM DUAL");
    }

}

Integrating with test frameworks

Sniffy provides integration with popular testing frameworks - see our wiki for details

Building

JDBC sniffer is built using JDK8+ and Maven 3.2+ - just checkout the project and type mvn install JDK8 is required only for building the project - once it's built, you can use Sniffy with any JRE 1.5+

UI part of Sniffy is maintained in a separate repository sniffy-ui

Contribute

You are most welcome to contribute to Sniffy!

Read the Contribution guidelines

sniffy's People

Contributors

bedrin avatar gitter-badger avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.