No SQL Unit - Devoxx 2012

485 views
369 views

Published on

Unit tests should follow the FIRST rules (Fast, Isolated, Repeatable, Self-Validated and Timely). When persistence layer is under test, fast and isolated rules are the most violated. For relational database management systems, embedded databases and DbUnit framework exist to help us to not break them, but there is no like DBUnit framework for heterogeneous NoSQL systems.

NoSQLUnit aids us to not break these rules by providing a JUnit extension which helps us to manage lifecycle of NoSQL systems and also it takes care of maintaining databases into known state. NoSQLUnit can be used during unit tests, but also in high level tests like integration or acceptance tests.

Published in: Technology, News & Politics
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
485
On SlideShare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

No SQL Unit - Devoxx 2012

  1. 1. NoSQLUnit Testing NoSQL Applications Alex Soto Bueno Computer Engineer lordofthejars.com @alexsotob
  2. 2. Carlo Strozzi Introduction
  3. 3. Carlo Strozzi Introduction 2000s
  4. 4. Carlo Strozzi Introduction 2000s
  5. 5. Carlo Strozzi Introduction 2000s No Standard Way
  6. 6. About Me Alex Soto Bueno Computer Engineer Diagnostic Grifols Tutor at UOC Active Blogger & Speaker
  7. 7. Theory
  8. 8. Theory FIRST Tests should Follow FIRST Rules
  9. 9. Theory Fast FIRST
  10. 10. Theory Isolation FIRST
  11. 11. Theory Repeatable FIRST
  12. 12. Theory Self-Validating FIRST
  13. 13. Theory Timely FIRST
  14. 14. Theory FIRST Fast Isolation Repeatable Self-Validating Timely Slow Isolation Repeatable Self-Validating Timely Unit High
  15. 15. Theory FIRST Testing Persistence Layer May Break Isolated Rule
  16. 16. Theory FIRSTpublic void savePhone(Phone phone) { ... } @Test public void should_insert_phone() { phoneService.save(new Phone()); } @Test public void should_count_phones() { int numberOfPhones = phoneService.count(); assertThat(numberOfPhones, equalTo(??)); }
  17. 17. Theory FIRST DBUnit
  18. 18. Theory FIRST DBUnit NoSQLUnit
  19. 19. Theory NoSQLUnit Manage Lifecycle
  20. 20. Theory NoSQLUnit Manage Lifecycle Maintain Database State
  21. 21. Theory NoSQLUnit Manage Lifecycle Maintain Database State Standardize Tests
  22. 22. Theory NoSQLUnit Two Groups JUnit Rules
  23. 23. Theory NoSQLUnit Two Groups JUnit Rules Two Annotations
  24. 24. Theory NoSQLUnit First Group: Start and Stop NoSQL Engine
  25. 25. Theory NoSQLUnit Second Group: Connection to Databases
  26. 26. Theory NoSQLUnit @UsingDataSet for Seeding Contents
  27. 27. Theory NoSQLUnit @ShouldMatchDataSet forVerifying Contents
  28. 28. Theory NoSQLUnit Start
  29. 29. Theory NoSQLUnit Start Clean
  30. 30. Theory NoSQLUnit Start Clean Populate
  31. 31. Theory NoSQLUnit Start Clean PopulateExecute
  32. 32. Theory NoSQLUnit Start Clean PopulateExecute Verify
  33. 33. Theory NoSQLUnit Start Clean PopulateExecute Verify Stop
  34. 34. Action
  35. 35. Action
  36. 36. Action Embedded InMemory Redis com.lordofthejars.nosqlunit.redis.EmbeddedRedis com.lordofthejars.nosqlunit.redis.ManagedRedis Managed Redis
  37. 37. Redis Connection com.lordofthejars.nosqlunit.redis.RedisRule Action
  38. 38. Action "data":[ {"simple": [{"key":"key1", "value":"value1"}] }, {"list": [{"key":"key3","values":[{"value":"value3"},{"value":"value4"}]}] }, {"sortset": [{"key":"key4","values":[ {"score":2, "value":"value5" },{"score":3, "value":1 }}] }] }, {"hash": [{"key":"user","values":[{"field":"name", "value":"alex"},]}] }, {"set":[{"key":"key3","values":[{"value":"value3"},{"value":"value4"}]}] } ]
  39. 39. Action Demo
  40. 40. Action
  41. 41. Action
  42. 42. Action Embedded Cassandra com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandra com.lordofthejars.nosqlunit.cassandra.ManagedCassandra Managed Cassandra
  43. 43. Cassandra Connection com.lordofthejars.nosqlunit.cassandra.CassandraRule Action
  44. 44. Action "name" : "keyspaceName", "columnFamilies" : [{ "name" : "columnFamilyName", "rows" : [{ "key" : "key10", "columns" : [{ "name" : "name11", "value" : "value11" }] }, { "name" : "otherColumnFamilyName", "type" : "SUPER", "rows" : [{ "key" : "10", "superColumns" : [{ "name" : "1100", "columns" : [{ "name" : "1110", "value" : "1110" }] } ]
  45. 45. Action
  46. 46. Action Embedded HBase com.lordofthejars.nosqlunit.hbase.EmbeddedHBase com.lordofthejars.nosqlunit.hbase.ManagedHBase Managed HBase
  47. 47. HBase Connection com.lordofthejars.nosqlunit.hbase.HBaseRule Action
  48. 48. Action "name" : "tablename", "columnFamilies" : [{ "name" : "columnFamilyName", "rows" : [{ "key" : "key1", "columns" : [{ "name" : "columnName", "value" : "columnValue" }, ... ] }, ... ] }, ... ]
  49. 49. Action
  50. 50. Action Embedded InMemory Neo4j com.lordofthejars.nosqlunit.neo4j.InMemoryNeo4j com.lordofthejars.nosqlunit.neo4j.EmbeddedNeo4j Embedded Neo4j Managed Wrapped Neo4j com.lordofthejars.nosqlunit.neo4j.ManagedWrappingNeoServer Managed Neo4j com.lordofthejars.nosqlunit.neo4j.ManagedNeoServer
  51. 51. Neo4j Connection com.lordofthejars.nosqlunit.neo4j.Neo4jRule Action
  52. 52. Action <?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns"> <key id="attr1" for="edge" attr.name="attr1" attr.type="float"/> <key id="attr2" for="node" attr.name="attr2" attr.type="string"/> <graph id="G" edgedefault="directed"> <node id="1"> <data key="attr2">value1</data> </node> <node id="2"> <data key="attr2">value2</data> </node> <edge id="7" source="1" target="2" label="label1"> <data key="attr1">float</data> </edge> </graph> </graphml>
  53. 53. Action Demo
  54. 54. Action
  55. 55. Action
  56. 56. Action Embedded InMemory MongoDB com.lordofthejars.nosqlunit.mongodb.InMemoryMongoDb com.lordofthejars.nosqlunit.mongodb.ManagedMongoDb Managed MongoDB
  57. 57. MongoDB Connection com.lordofthejars.nosqlunit.mongodb.MongoDbRule Action
  58. 58. Action { "name_collection1": [ { "attribute_1":"value1", "attribute_2":"value2" }, { "attribute_3":2, "attribute_4":"value4" } ], "name_collection2": [ ... ], .... }
  59. 59. More
  60. 60. Action NoSQLUnit NoSQLUnit is Ready for the clouds No lifecycle management
  61. 61. Action Demo NoSQLUnit
  62. 62. Action NoSQLUnit Acceptance Tests Cloud
  63. 63. Action NoSQLUnit NoSQL system may be polyglot Populating different data in parallel
  64. 64. Action NoSQLUnit private final Neo4jConfiguration neo4jConfiguration = newManagedNeoServerConfiguration().connectionIdentifier("neo4j").build(); @Rule public final Neo4jRule neo4jRule = newNeo4jRule().configure(neo4jConfiguration).build(); private final RedisConfiguration redisConfiguration = newManagedRedisConfiguration().connectionIdentifier("redis").build(); @Rule public final RedisRule redisRule = newRedisRule().configure(redisConfiguration).build(); @Test @UsingDataSet(withSelectiveLocations = { ! @Selective(identifier = "neo4j", locations = "matrix.xml"), ! @Selective(identifier = "redis", locations = "matrix.json") }, ! loadStrategy = LoadStrategyEnum.CLEAN_INSERT) public void cached_friends_should_be_returned() {...}
  65. 65. Action NoSQLUnit private final Neo4jConfiguration neo4jConfiguration = newManagedNeoServerConfiguration().connectionIdentifier("neo4j").build(); @Rule public final Neo4jRule neo4jRule = newNeo4jRule().configure(neo4jConfiguration).build(); private final RedisConfiguration redisConfiguration = newManagedRedisConfiguration().connectionIdentifier("redis").build(); @Rule public final RedisRule redisRule = newRedisRule().configure(redisConfiguration).build(); @Test @UsingDataSet(withSelectiveLocations = { ! @Selective(identifier = "neo4j", locations = "matrix.xml"), ! @Selective(identifier = "redis", locations = "matrix.json") }, ! loadStrategy = LoadStrategyEnum.CLEAN_INSERT) public void cached_friends_should_be_returned() {...}
  66. 66. Action NoSQLUnit private final Neo4jConfiguration neo4jConfiguration = newManagedNeoServerConfiguration().connectionIdentifier("neo4j").build(); @Rule public final Neo4jRule neo4jRule = newNeo4jRule().configure(neo4jConfiguration).build(); private final RedisConfiguration redisConfiguration = newManagedRedisConfiguration().connectionIdentifier("redis").build(); @Rule public final RedisRule redisRule = newRedisRule().configure(redisConfiguration).build(); @Test @UsingDataSet(withSelectiveLocations = { ! @Selective(identifier = "neo4j", locations = "matrix.xml"), ! @Selective(identifier = "redis", locations = "matrix.json") }, ! loadStrategy = LoadStrategyEnum.CLEAN_INSERT) public void cached_friends_should_be_returned() {...}
  67. 67. Action NoSQLUnit Partial Support for JSR-330 @Inject @Named
  68. 68. Action NoSQLUnit Rule public final MongoDbRule mongoDb = newMongoDbRule().defaultManagedMongoDb(“test”, this); @Inject private Mongo mongo;
  69. 69. Action Flashback NoSQLUnit
  70. 70. Action Spring Data MongoDB - _class attribute Spring Data Redis - Serializer/OXM/JSON Spring Data HBase - RowMapper interface Spring Data Neo4j - __type__ attribute Spring Data Cassandra - EntityWritter interface Spring Data
  71. 71. Action Hibernate MongoDB - name property Hibernate
  72. 72. What’s Coming
  73. 73. What’s Coming Engines
  74. 74. What’s Coming Integration
  75. 75. What’s Coming Integration https://github.com/lordofthejars/nosql-unit/issues
  76. 76. Conclusions
  77. 77. Conclusions Hard and Tedious Job Spiderman way
  78. 78. Conclusions Spiderman way
  79. 79. Conclusions Spiderman way
  80. 80. Conclusions Spiderman way
  81. 81. Thank you
  82. 82. Questions Questions
  83. 83. NoSQLUnit Testing NoSQL Applications Alex Soto Bueno Computer Engineer lordofthejars.com @alexsotob Umi no kanatani wa mou sagasanai, Kagayaku monowa itsumo kokoni (Itsumo Nando De Mo)
  84. 84. NoSQLUnit Testing NoSQL Applications Alex Soto Bueno Computer Engineer lordofthejars.com @alexsotob
  85. 85. CC Photos

×