Test-driven development: a case study
Upcoming SlideShare
Loading in...5
×
 

Test-driven development: a case study

on

  • 1,455 views

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

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

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

Statistics

Views

Total Views
1,455
Views on SlideShare
1,399
Embed Views
56

Actions

Likes
0
Downloads
7
Comments
0

2 Embeds 56

http://japhy.soup.io 53
http://a0.twimg.com 3

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Test-driven development: a case study Test-driven development: a case study Presentation Transcript

  • TDD
  • RED GREENREFACTOR
  • Effect?
  • More code
  • More simple code
  • More simple code, delivered faster
  • Cleanerinterfaces
  • Betterunderstanding of codebase
  • Fast & precise regression discovery
  • Easyrefactoring
  • Casestudy
  • Things come together. Semantic socialcollaboration platform
  • Things come together.Python/DjangoPostgreSQLApache SolrCustom Java backend
  • RDF-based APIsGraphs of linked dataURIs as identifiersSubject-Predicate-Objecttriples
  • <_: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/> .
  • 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 ... ...
  • 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;
  • NoSQL?
  • NoSQL?
  • “How FriendFeeduses MySQL to store schema-less data”-- http://bret.appspot.com/entry/how-friendfeed-uses-mysql
  • Use PostgreSQLas RDF document-oriented database
  • Single Thing classMany concreteAnnotation classesTEXT field `attributes’for free-form RDF
  • No JOINs
  • RulesKeep existing code(when possible)Keep existing behaviourKeep magic localized
  • I. New codeRDFField & URIRefField usingrdflibCustomized RDF serialization
  • II. AnalysisExtract existing schema frommodel codeDeclare schema in RDFGlue code for attribute access toRDF data
  • 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 .
  • 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])
  • III. DetailsRun test suiteFind most common errorAdapt test or change codeRepeat for three weeks
  • IV. TweakingData migrationRefactor APIsOptimize
  • Success!
  • Things come together.http://www.getrefinder.com/