Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Test-driven development: a case study

1.759 visualizaciones

Publicado el

How test-driven development enabled Gnowsis to reimplement Refinder's basic data model.

Talk at Warsaw DjangoPiwo meetup on 2011-11-02.

Publicado en: Tecnología, Educación
  • Inicia sesión para ver los comentarios

  • Sé el primero en recomendar esto

Test-driven development: a case study

  1. 1. TDD
  2. 2. RED GREENREFACTOR
  3. 3. Effect?
  4. 4. More code
  5. 5. More simple code
  6. 6. More simple code, delivered faster
  7. 7. Cleanerinterfaces
  8. 8. Betterunderstanding of codebase
  9. 9. Fast & precise regression discovery
  10. 10. Easyrefactoring
  11. 11. Casestudy
  12. 12. Things come together. Semantic socialcollaboration platform
  13. 13. Things come together.Python/DjangoPostgreSQLApache SolrCustom Java backend
  14. 14. RDF-based APIsGraphs of linked dataURIs as identifiersSubject-Predicate-Objecttriples
  15. 15. <_:me> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .<_:me> <http://xmlns.com/foaf/0.1/family_name> "Pasternacki" .<_:me> <http://xmlns.com/foaf/0.1/givenname> "Maciej" .<_:me> <http://xmlns.com/foaf/0.1/homepage> <http://www.pasternacki.net/> .<_:me> <http://xmlns.com/foaf/0.1/mbox> <mailto:maciej@pasternacki.net> .<_:me> <http://xmlns.com/foaf/0.1/name> "Maciej Pasternacki" .<_:me> <http://xmlns.com/foaf/0.1/nick> "japhy" .<_:me> <http://xmlns.com/foaf/0.1/workplaceHomepage> <http://www.gnowsis.com/> . @prefix : <#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . :me a foaf:Person . :me foaf:family_name "Pasternacki" . :me foaf:givenname "Maciej" . :me foaf:homepage <http://www.pasternacki.net/> . :me foaf:mbox <mailto:maciej@pasternacki.net> . :me foaf:name "Maciej Pasternacki" . :me foaf:nick "japhy" . :me foaf:workplaceHomepage <http://www.gnowsis.com/> .
  16. 16. Item Relation uuid : uuid type : uri rdf_type : URI * label : string created : dateTime lastModified: dateTime Description text : string target (1) Thing Annotation Rating value : normalizedFloat InformationElement Wiki text : string Property File type : uripath : string lexicalForm : stringmimeType : string... Webpage url : string summary : string StringProperty Email subject : string value : string ... IntProperty value : integer Blogpost Tweet DatetimeProperty timestamp : dateTime author : string value : datetime author : string text : string ... ...
  17. 17. def promote(self): if not hasattr(self, _promoted): if isinstance(self, self.get_class()): self._promoted = self else: self._promoted = getattr( self, getattr( self.get_class(), self._root_class_name + _ptr ).field.related_query_name() ) return self._promotedSELECT … FROM "pim_annotation"LEFT OUTER JOIN "pim_related"ON ("pim_annotation"."id" = "pim_related"."annotation_ptr_id")WHERE ( "pim_annotation"."thing_id" = E∴ OR "pim_related"."related_to_id" = E∴ )ORDER BY "pim_annotation"."lastModified" DESC;
  18. 18. NoSQL?
  19. 19. NoSQL?
  20. 20. “How FriendFeeduses MySQL to store schema-less data”-- http://bret.appspot.com/entry/how-friendfeed-uses-mysql
  21. 21. Use PostgreSQLas RDF document-oriented database
  22. 22. Single Thing classMany concreteAnnotation classesTEXT field `attributes’for free-form RDF
  23. 23. No JOINs
  24. 24. RulesKeep existing code(when possible)Keep existing behaviourKeep magic localized
  25. 25. I. New codeRDFField & URIRefField usingrdflibCustomized RDF serialization
  26. 26. II. AnalysisExtract existing schema frommodel codeDeclare schema in RDFGlue code for attribute access toRDF data
  27. 27. nfo:Bookmark rdfs:subClassOf pimo:Thing ; grfs:className "Bookmark" ; grfs:label "nfo:Bookmark" ; grfs:pluralLabel "nfo:Bookmarks" ; grfs:isGuiCreatable "true"^^xsd:boolean ; grfs:labelProperties ( dct:title rdfs:label nfo:bookmarks ) ; grfs:shortSummaryInfoProperties ( nfo:bookmarks ) .nao:description a rdfs:Property ; rdfs:domain pimo:Thing, pimo:Person, pimo:Event, nfo:Bookmark,pimo:Project, pimo:Person, nfo:FileDataObject, pimo:Topic, pimo:Location,pimo:Task, nmo:Email, pimo:Question, pimo:Organization, pimo:Note,pimo:Collection; grfs:attributeName "description" ; grfs:ftsFullText "true"^^xsd:boolean ; grfs:additionalShortSummaryInfo "false"^^xsd:boolean .nfo:bookmarks a rdfs:Property ; rdfs:domain nfo:Bookmark ; grfs:attributeName "bookmarks" ; grfs:ftsFullText "true"^^xsd:boolean ; grfs:additionalShortSummaryInfo "true"^^xsd:boolean .
  28. 28. SELF_URI = URIRef(self:#)def __getattr__(self, attr): property_uri = attribute_uri(attr) oo = list(self.attributes.objects( self.SELF_URI, property_uri)) if not oo: raise AttributeError(attr) if len(oo) == 1: return oo[0].toPython() return set([o.toPython() for o in oo])
  29. 29. III. DetailsRun test suiteFind most common errorAdapt test or change codeRepeat for three weeks
  30. 30. IV. TweakingData migrationRefactor APIsOptimize
  31. 31. Success!
  32. 32. Things come together.http://www.getrefinder.com/

×